diff --git a/src/386.d b/src/386.d new file mode 100644 index 000000000..d3ddfcb52 --- /dev/null +++ b/src/386.d @@ -0,0 +1,4 @@ +386.o: cpu_common/386.c 86box.h cpu_common/cpu.h timer.h cpu_common/cpu.h \ + cpu_common/x86.h cpu_common/x87.h nmi.h mem.h pic.h pit.h floppy/fdd.h \ + floppy/fdc.h cpu_common/386_common.h cpu/x86_flags.h \ + cpu_common/x86_ops.h diff --git a/src/386.txt b/src/386.txt new file mode 100644 index 000000000..18686e42d --- /dev/null +++ b/src/386.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386.c and CPU_NEW\386.C +FC: no differences encountered + diff --git a/src/386_common.d b/src/386_common.d new file mode 100644 index 000000000..477b19fd7 --- /dev/null +++ b/src/386_common.d @@ -0,0 +1,4 @@ +386_common.o: cpu_common/386_common.c 86box.h cpu_common/cpu.h timer.h \ + cpu_common/cpu.h cpu_common/x86.h cpu_common/x87.h nmi.h mem.h pic.h \ + pit.h floppy/fdd.h floppy/fdc.h cpu_common/386_common.h cpu/x86_flags.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h diff --git a/src/386_common.txt b/src/386_common.txt new file mode 100644 index 000000000..09472e03d --- /dev/null +++ b/src/386_common.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386_common.h and CPU_NEW\386_COMMON.H +FC: no differences encountered + diff --git a/src/386_dynarec.d b/src/386_dynarec.d new file mode 100644 index 000000000..792b65683 --- /dev/null +++ b/src/386_dynarec.d @@ -0,0 +1,25 @@ +386_dynarec.o: cpu_common/386_dynarec.c 86box.h cpu_common/cpu.h \ + cpu_common/x86.h cpu_common/x86_ops.h cpu_common/x87.h 86box_io.h mem.h \ + nmi.h pic.h timer.h cpu_common/cpu.h floppy/fdd.h floppy/fdc.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h \ + cpu_common/386_common.h cpu/x86_flags.h cpu_common/386_ops.h \ + cpu_common/x86seg.h cpu_common/x86_ops_arith.h \ + cpu_common/x86_ops_atomic.h cpu_common/x86_ops_bcd.h \ + cpu_common/x86_ops_bit.h cpu_common/x86_ops_bitscan.h \ + cpu_common/x86_ops_flag.h cpu_common/x86_ops_fpu.h \ + cpu_common/x86_ops_inc_dec.h cpu_common/x86_ops_int.h \ + cpu_common/x86_ops_io.h cpu_common/x86_ops_jump.h \ + cpu_common/x86_ops_misc.h cpu_common/x87_ops.h \ + cpu_common/x87_ops_arith.h cpu_common/x87_ops_misc.h \ + cpu_common/x87_ops_loadstore.h cpu_common/x86_ops_i686.h \ + cpu_common/x86_ops_mmx.h cpu_common/x86_ops_mmx_arith.h \ + cpu_common/x86_ops_mmx_cmp.h cpu_common/x86_ops_mmx_logic.h \ + cpu_common/x86_ops_mmx_mov.h cpu_common/x86_ops_mmx_pack.h \ + cpu_common/x86_ops_mmx_shift.h cpu_common/x86_ops_mov.h \ + cpu_common/x86_ops_mov_ctrl.h cpu_common/x86_ops_mov_seg.h \ + cpu_common/x86_ops_movx.h cpu_common/x86_ops_msr.h \ + cpu_common/x86_ops_mul.h cpu_common/x86_ops_pmode.h \ + cpu_common/x86_ops_prefix.h cpu_common/x86_ops_rep.h \ + cpu_common/x86_ops_ret.h cpu_common/x86_ops_set.h \ + cpu_common/x86_ops_stack.h cpu_common/x86_ops_string.h \ + cpu_common/x86_ops_xchg.h cpu/x86_ops_call.h cpu/x86_ops_shift.h diff --git a/src/386_dynarec.txt b/src/386_dynarec.txt new file mode 100644 index 000000000..0ceb013df --- /dev/null +++ b/src/386_dynarec.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386_dynarec.c and CPU_NEW\386_DYNAREC.C +FC: no differences encountered + diff --git a/src/386_dynarec_ops.d b/src/386_dynarec_ops.d new file mode 100644 index 000000000..4af90ccb2 --- /dev/null +++ b/src/386_dynarec_ops.d @@ -0,0 +1,24 @@ +386_dynarec_ops.o: cpu_common/386_dynarec_ops.c 86box.h cpu_common/cpu.h \ + timer.h cpu_common/cpu.h cpu_common/x86.h cpu_common/x86_ops.h \ + cpu_common/x87.h cpu/x86_flags.h 86box_io.h mem.h nmi.h pic.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h \ + cpu_common/386_common.h cpu_common/386_ops.h cpu_common/x86seg.h \ + cpu_common/x86_ops_arith.h cpu_common/x86_ops_atomic.h \ + cpu_common/x86_ops_bcd.h cpu_common/x86_ops_bit.h \ + cpu_common/x86_ops_bitscan.h cpu_common/x86_ops_flag.h \ + cpu_common/x86_ops_fpu.h cpu_common/x86_ops_inc_dec.h \ + cpu_common/x86_ops_int.h cpu_common/x86_ops_io.h \ + cpu_common/x86_ops_jump.h cpu_common/x86_ops_misc.h cpu_common/x87_ops.h \ + cpu_common/x87_ops_arith.h cpu_common/x87_ops_misc.h \ + cpu_common/x87_ops_loadstore.h cpu_common/x86_ops_i686.h \ + cpu_common/x86_ops_mmx.h cpu_common/x86_ops_mmx_arith.h \ + cpu_common/x86_ops_mmx_cmp.h cpu_common/x86_ops_mmx_logic.h \ + cpu_common/x86_ops_mmx_mov.h cpu_common/x86_ops_mmx_pack.h \ + cpu_common/x86_ops_mmx_shift.h cpu_common/x86_ops_mov.h \ + cpu_common/x86_ops_mov_ctrl.h cpu_common/x86_ops_mov_seg.h \ + cpu_common/x86_ops_movx.h cpu_common/x86_ops_msr.h \ + cpu_common/x86_ops_mul.h cpu_common/x86_ops_pmode.h \ + cpu_common/x86_ops_prefix.h cpu_common/x86_ops_rep.h \ + cpu_common/x86_ops_ret.h cpu_common/x86_ops_set.h \ + cpu_common/x86_ops_stack.h cpu_common/x86_ops_string.h \ + cpu_common/x86_ops_xchg.h cpu/x86_ops_call.h cpu/x86_ops_shift.h diff --git a/src/386_dynarec_ops.txt b/src/386_dynarec_ops.txt new file mode 100644 index 000000000..47a24c719 --- /dev/null +++ b/src/386_dynarec_ops.txt @@ -0,0 +1,3 @@ +Comparing files CPU\386_dynarec_ops.c and CPU_NEW\386_DYNAREC_OPS.C +FC: no differences encountered + diff --git a/src/386_ops.txt b/src/386_ops.txt new file mode 100644 index 000000000..b16faec06 --- /dev/null +++ b/src/386_ops.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops.h and CPU_NEW\X86_OPS.H +FC: no differences encountered + diff --git a/src/808x.d b/src/808x.d new file mode 100644 index 000000000..464d381c1 --- /dev/null +++ b/src/808x.d @@ -0,0 +1,5 @@ +808x.o: cpu_common/808x.c 86box.h cpu_common/cpu.h cpu_common/x86.h \ + machine/machine.h 86box_io.h mem.h rom.h nmi.h pic.h timer.h \ + cpu_common/cpu.h cpu_common/x87.h cpu_common/x87_ops.h \ + cpu_common/x87_ops_arith.h cpu_common/x87_ops_misc.h \ + cpu_common/x87_ops_loadstore.h diff --git a/src/808x.txt b/src/808x.txt new file mode 100644 index 000000000..78b95f4ac --- /dev/null +++ b/src/808x.txt @@ -0,0 +1,205 @@ +Comparing files CPU\808x.c and CPU_NEW\808X.C +***** CPU\808x.c + * + * Version: @(#)808x.c 1.0.11 2019/10/21 + * +***** CPU_NEW\808X.C + * + * Version: @(#)808x.c 1.0.9 2019/02/13 + * +***** + +***** CPU\808x.c +#include + +#define HAVE_STDARG_H +***** CPU_NEW\808X.C +#include +#define HAVE_STDARG_H +***** + +***** CPU\808x.c +int nmi = 0, nmi_auto_clear = 0; +int nmi_enable = 1; + +***** CPU_NEW\808X.C +int nmi = 0, nmi_auto_clear = 0; + +***** + +***** CPU\808x.c + + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then +***** CPU_NEW\808X.C + + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then +***** + +***** CPU\808x.c + pfq_add(c, !bus); + if (bus < 2) { + // clock_end(); + // clock_start(); + } +} +***** CPU_NEW\808X.C + pfq_add(c, !bus); + clock_end(); + clock_start(); +} +***** + +***** CPU\808x.c +{ + if (c <= 0) + return; + + cycles -= c; +***** CPU_NEW\808X.C +{ + cycles -= c; +***** + +***** CPU\808x.c + if (!is286) + fetch_and_bus(c, 2); +} +***** CPU_NEW\808X.C + if (!is286) + fetch_and_bus(c, 1); +} +***** + +***** CPU\808x.c + +static uint32_t +sign_extend32(uint16_t data) +{ + return data + (data < 0x8000 ? 0 : 0xffff0000); +} + + +/* Fetches the effective address from the prefetch queue according to MOD and R/M. */ +***** CPU_NEW\808X.C + +/* Fetches the effective address from the prefetch queue according to MOD and R/M. */ +***** + +***** CPU\808x.c + cpu_state.pc = 0xFFF0; + cpu_state.seg_cs.base = 0xFFFF0000; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; +***** CPU_NEW\808X.C + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; +***** + +***** CPU\808x.c + resetmcr(); + cpu_set_edx(); +***** CPU_NEW\808X.C + resetmcr(); + pfq_clear(); + cpu_set_edx(); +***** + +***** CPU\808x.c +#endif + if (!hard) + flushmmucache(); + x86_was_reset = 1; +***** CPU_NEW\808X.C +#endif + if (!hard) + flushmmucache(); + x86_was_reset = 1; +***** + +***** CPU\808x.c + + pfq_clear(); + prefetching = 1; + + takeint = 0; +***** CPU_NEW\808X.C + + prefetching = 1; + takeint = 0; +***** + +***** CPU\808x.c + cpu_ven_reset(); + + cpu_alu_op = 0; +} +***** CPU_NEW\808X.C + cpu_ven_reset(); +} +***** + +***** CPU\808x.c + + /* This has to be done so that the special case of ADD does not kick in. */ + size_mask = (1 << bit_count) - 1; +***** CPU_NEW\808X.C + + size_mask = (1 << bit_count) - 1; +***** + +***** CPU\808x.c + uint16_t new_cs, new_ip; + uint32_t result; + int bits; +***** CPU_NEW\808X.C + uint16_t new_cs, new_ip; + int bits; +***** + +***** CPU\808x.c + if (opcode & 1) { + result = cpu_data; + mul(AX, cpu_data); +***** CPU_NEW\808X.C + if (opcode & 1) { + mul(AX, cpu_data); +***** + +***** CPU\808x.c + cpu_data |= DX; + result = ((uint32_t) DX << 16) | AX; + if ((rmdat & 0x38) == 0x20) + set_co_mul(DX != 0x0000); + else + set_co_mul(result != sign_extend32(AX)); + } else { +***** CPU_NEW\808X.C + cpu_data |= DX; + set_co_mul(DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + } else { +***** + +***** CPU\808x.c + cpu_data |= AH; + if ((rmdat & 0x38) == 0x20) + set_co_mul(AH != 0x00); + else + set_co_mul(AX != sign_extend(AL)); + } +***** CPU_NEW\808X.C + cpu_data |= AH; + set_co_mul(AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + } +***** + +***** CPU\808x.c + noint = 0; + + cpu_alu_op = 0; + } +***** CPU_NEW\808X.C + noint = 0; + } +***** + diff --git a/src/io.h b/src/86box_io.h similarity index 100% rename from src/io.h rename to src/86box_io.h diff --git a/src/Analog.d b/src/Analog.d new file mode 100644 index 000000000..cbca6f037 --- /dev/null +++ b/src/Analog.d @@ -0,0 +1,3 @@ +Analog.o: sound/munt/Analog.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/Analog.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Enumerations.h sound/munt/Synth.h diff --git a/src/BReverbModel.d b/src/BReverbModel.d new file mode 100644 index 000000000..4161da655 --- /dev/null +++ b/src/BReverbModel.d @@ -0,0 +1,3 @@ +BReverbModel.o: sound/munt/BReverbModel.cpp sound/munt/internals.h \ + sound/munt/Types.h sound/munt/BReverbModel.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/Enumerations.h sound/munt/Synth.h diff --git a/src/File.d b/src/File.d new file mode 100644 index 000000000..0d35ddd62 --- /dev/null +++ b/src/File.d @@ -0,0 +1,3 @@ +File.o: sound/munt/File.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/File.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/sha1/sha1.h diff --git a/src/FileStream.d b/src/FileStream.d new file mode 100644 index 000000000..a992fa85c --- /dev/null +++ b/src/FileStream.d @@ -0,0 +1,3 @@ +FileStream.o: sound/munt/FileStream.cpp sound/munt/internals.h \ + sound/munt/Types.h sound/munt/FileStream.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/File.h diff --git a/src/LA32FloatWaveGenerator.d b/src/LA32FloatWaveGenerator.d new file mode 100644 index 000000000..0adecf1e7 --- /dev/null +++ b/src/LA32FloatWaveGenerator.d @@ -0,0 +1,5 @@ +LA32FloatWaveGenerator.o: sound/munt/LA32FloatWaveGenerator.cpp \ + sound/munt/internals.h sound/munt/Types.h \ + sound/munt/LA32FloatWaveGenerator.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/LA32WaveGenerator.h sound/munt/mmath.h \ + sound/munt/Tables.h diff --git a/src/LA32Ramp.d b/src/LA32Ramp.d new file mode 100644 index 000000000..0ae8968e1 --- /dev/null +++ b/src/LA32Ramp.d @@ -0,0 +1,3 @@ +LA32Ramp.o: sound/munt/LA32Ramp.cpp sound/munt/internals.h \ + sound/munt/Types.h sound/munt/LA32Ramp.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/Tables.h diff --git a/src/LA32WaveGenerator.d b/src/LA32WaveGenerator.d new file mode 100644 index 000000000..2e9bcb5f0 --- /dev/null +++ b/src/LA32WaveGenerator.d @@ -0,0 +1,3 @@ +LA32WaveGenerator.o: sound/munt/LA32WaveGenerator.cpp \ + sound/munt/internals.h sound/munt/Types.h sound/munt/LA32WaveGenerator.h \ + sound/munt/globals.h sound/munt/config.h sound/munt/Tables.h diff --git a/src/MidiStreamParser.d b/src/MidiStreamParser.d new file mode 100644 index 000000000..35b721c7d --- /dev/null +++ b/src/MidiStreamParser.d @@ -0,0 +1,4 @@ +MidiStreamParser.o: sound/munt/MidiStreamParser.cpp \ + sound/munt/internals.h sound/munt/Types.h sound/munt/MidiStreamParser.h \ + sound/munt/globals.h sound/munt/config.h sound/munt/Synth.h \ + sound/munt/Enumerations.h diff --git a/src/Part.d b/src/Part.d new file mode 100644 index 000000000..644871474 --- /dev/null +++ b/src/Part.d @@ -0,0 +1,6 @@ +Part.o: sound/munt/Part.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/Part.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Structures.h sound/munt/Partial.h sound/munt/LA32Ramp.h \ + sound/munt/LA32WaveGenerator.h sound/munt/LA32FloatWaveGenerator.h \ + sound/munt/PartialManager.h sound/munt/Poly.h sound/munt/Synth.h \ + sound/munt/Enumerations.h diff --git a/src/Partial.d b/src/Partial.d new file mode 100644 index 000000000..562b7bd2d --- /dev/null +++ b/src/Partial.d @@ -0,0 +1,7 @@ +Partial.o: sound/munt/Partial.cpp sound/munt/internals.h \ + sound/munt/Types.h sound/munt/Partial.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/Structures.h sound/munt/LA32Ramp.h \ + sound/munt/LA32WaveGenerator.h sound/munt/LA32FloatWaveGenerator.h \ + sound/munt/Part.h sound/munt/Poly.h sound/munt/Synth.h \ + sound/munt/Enumerations.h sound/munt/Tables.h sound/munt/TVA.h \ + sound/munt/TVF.h sound/munt/TVP.h diff --git a/src/PartialManager.d b/src/PartialManager.d new file mode 100644 index 000000000..5a22d83f1 --- /dev/null +++ b/src/PartialManager.d @@ -0,0 +1,6 @@ +PartialManager.o: sound/munt/PartialManager.cpp sound/munt/internals.h \ + sound/munt/Types.h sound/munt/PartialManager.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/Part.h sound/munt/Structures.h \ + sound/munt/Partial.h sound/munt/LA32Ramp.h \ + sound/munt/LA32WaveGenerator.h sound/munt/LA32FloatWaveGenerator.h \ + sound/munt/Poly.h sound/munt/Synth.h sound/munt/Enumerations.h diff --git a/src/Poly.d b/src/Poly.d new file mode 100644 index 000000000..fde8cbbf4 --- /dev/null +++ b/src/Poly.d @@ -0,0 +1,6 @@ +Poly.o: sound/munt/Poly.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/Poly.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Part.h sound/munt/Structures.h sound/munt/Partial.h \ + sound/munt/LA32Ramp.h sound/munt/LA32WaveGenerator.h \ + sound/munt/LA32FloatWaveGenerator.h sound/munt/Synth.h \ + sound/munt/Enumerations.h diff --git a/src/ROMInfo.d b/src/ROMInfo.d new file mode 100644 index 000000000..50f90481f --- /dev/null +++ b/src/ROMInfo.d @@ -0,0 +1,3 @@ +ROMInfo.o: sound/munt/ROMInfo.cpp sound/munt/internals.h \ + sound/munt/Types.h sound/munt/ROMInfo.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/File.h diff --git a/src/SampleRateConverter_dummy.d b/src/SampleRateConverter_dummy.d new file mode 100644 index 000000000..0cf1c31c6 --- /dev/null +++ b/src/SampleRateConverter_dummy.d @@ -0,0 +1,5 @@ +SampleRateConverter_dummy.o: sound/munt/SampleRateConverter_dummy.cpp \ + sound/munt/../../plat.h sound/munt/../../lang/language.h \ + sound/munt/SampleRateConverter.h sound/munt/globals.h \ + sound/munt/config.h sound/munt/Types.h sound/munt/Enumerations.h \ + sound/munt/Synth.h diff --git a/src/Synth.d b/src/Synth.d new file mode 100644 index 000000000..0152c1a05 --- /dev/null +++ b/src/Synth.d @@ -0,0 +1,8 @@ +Synth.o: sound/munt/Synth.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/Synth.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Enumerations.h sound/munt/Analog.h sound/munt/BReverbModel.h \ + sound/munt/File.h sound/munt/MemoryRegion.h sound/munt/Structures.h \ + sound/munt/MidiEventQueue.h sound/munt/Part.h sound/munt/Partial.h \ + sound/munt/LA32Ramp.h sound/munt/LA32WaveGenerator.h \ + sound/munt/LA32FloatWaveGenerator.h sound/munt/PartialManager.h \ + sound/munt/Poly.h sound/munt/ROMInfo.h sound/munt/TVA.h diff --git a/src/TVA.d b/src/TVA.d new file mode 100644 index 000000000..01d1ce78b --- /dev/null +++ b/src/TVA.d @@ -0,0 +1,6 @@ +TVA.o: sound/munt/TVA.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/TVA.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Structures.h sound/munt/Part.h sound/munt/Partial.h \ + sound/munt/LA32Ramp.h sound/munt/LA32WaveGenerator.h \ + sound/munt/LA32FloatWaveGenerator.h sound/munt/Poly.h sound/munt/Synth.h \ + sound/munt/Enumerations.h sound/munt/Tables.h diff --git a/src/TVF.d b/src/TVF.d new file mode 100644 index 000000000..6925b87ef --- /dev/null +++ b/src/TVF.d @@ -0,0 +1,6 @@ +TVF.o: sound/munt/TVF.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/TVF.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Structures.h sound/munt/LA32Ramp.h sound/munt/Partial.h \ + sound/munt/LA32WaveGenerator.h sound/munt/LA32FloatWaveGenerator.h \ + sound/munt/Poly.h sound/munt/Synth.h sound/munt/Enumerations.h \ + sound/munt/Tables.h diff --git a/src/TVP.d b/src/TVP.d new file mode 100644 index 000000000..0e895a6d1 --- /dev/null +++ b/src/TVP.d @@ -0,0 +1,6 @@ +TVP.o: sound/munt/TVP.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/TVP.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/Structures.h sound/munt/Part.h sound/munt/Partial.h \ + sound/munt/LA32Ramp.h sound/munt/LA32WaveGenerator.h \ + sound/munt/LA32FloatWaveGenerator.h sound/munt/Poly.h sound/munt/Synth.h \ + sound/munt/Enumerations.h sound/munt/TVA.h diff --git a/src/Tables.d b/src/Tables.d new file mode 100644 index 000000000..0d2008b5f --- /dev/null +++ b/src/Tables.d @@ -0,0 +1,3 @@ +Tables.o: sound/munt/Tables.cpp sound/munt/internals.h sound/munt/Types.h \ + sound/munt/Tables.h sound/munt/globals.h sound/munt/config.h \ + sound/munt/mmath.h diff --git a/src/acc2168.d b/src/acc2168.d new file mode 100644 index 000000000..b3af53f0d --- /dev/null +++ b/src/acc2168.d @@ -0,0 +1,3 @@ +acc2168.o: chipset/acc2168.c 86box.h cpu_common/cpu.h timer.h device.h \ + keyboard.h 86box_io.h mem.h mouse.h port_92.h sio.h disk/hdc.h \ + video/video.h chipset/chipset.h diff --git a/src/acer_m3a.d b/src/acer_m3a.d new file mode 100644 index 000000000..686b971eb --- /dev/null +++ b/src/acer_m3a.d @@ -0,0 +1,2 @@ +acer_m3a.o: chipset/acer_m3a.c 86box.h mem.h 86box_io.h rom.h pci.h \ + device.h keyboard.h chipset/chipset.h diff --git a/src/ali1429.d b/src/ali1429.d new file mode 100644 index 000000000..5267cb13c --- /dev/null +++ b/src/ali1429.d @@ -0,0 +1,3 @@ +ali1429.o: chipset/ali1429.c 86box.h cpu_common/cpu.h timer.h 86box_io.h \ + mem.h device.h keyboard.h floppy/fdd.h floppy/fdc.h disk/hdc.h \ + disk/hdc_ide.h port_92.h chipset/chipset.h diff --git a/src/apm.c b/src/apm.c index 1ec2fb6de..27c33474e 100644 --- a/src/apm.c +++ b/src/apm.c @@ -21,9 +21,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "device.h" -#include "io.h" +#include "86box_io.h" typedef struct diff --git a/src/apm_new.c b/src/apm_new.c index a0963cade..2ae56d82e 100644 --- a/src/apm_new.c +++ b/src/apm_new.c @@ -21,9 +21,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu_new/cpu.h" +#include "cpu.h" #include "device.h" -#include "io.h" +#include "86box_io.h" typedef struct diff --git a/src/apm_new.d b/src/apm_new.d new file mode 100644 index 000000000..7a0b1ece9 --- /dev/null +++ b/src/apm_new.d @@ -0,0 +1 @@ +apm_new.o: apm_new.c 86box.h cpu_common/cpu.h device.h 86box_io.h diff --git a/src/bootp.d b/src/bootp.d new file mode 100644 index 000000000..8064c7bbd --- /dev/null +++ b/src/bootp.d @@ -0,0 +1,9 @@ +bootp.o: network/slirp/bootp.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/bugger.c b/src/bugger.c index cd2d843d9..7205ea25d 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -56,7 +56,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "device.h" #include "plat.h" #include "ui.h" diff --git a/src/bugger.d b/src/bugger.d new file mode 100644 index 000000000..d03d9539d --- /dev/null +++ b/src/bugger.d @@ -0,0 +1,2 @@ +bugger.o: bugger.c 86box.h 86box_io.h device.h plat.h lang/language.h \ + ui.h bugger.h diff --git a/src/c_interface.d b/src/c_interface.d new file mode 100644 index 000000000..867dc3935 --- /dev/null +++ b/src/c_interface.d @@ -0,0 +1,12 @@ +c_interface.o: sound/munt/c_interface/c_interface.cpp \ + sound/munt/c_interface/../globals.h sound/munt/c_interface/../config.h \ + sound/munt/c_interface/../Types.h sound/munt/c_interface/../File.h \ + sound/munt/c_interface/../globals.h sound/munt/c_interface/../Types.h \ + sound/munt/c_interface/../FileStream.h sound/munt/c_interface/../File.h \ + sound/munt/c_interface/../ROMInfo.h sound/munt/c_interface/../Synth.h \ + sound/munt/c_interface/../Enumerations.h \ + sound/munt/c_interface/../MidiStreamParser.h \ + sound/munt/c_interface/../SampleRateConverter.h \ + sound/munt/c_interface/c_types.h \ + sound/munt/c_interface/../Enumerations.h \ + sound/munt/c_interface/c_interface.h diff --git a/src/cassette/cassette.c b/src/cassette/cassette.c deleted file mode 100644 index b9ba8a7ca..000000000 --- a/src/cassette/cassette.c +++ /dev/null @@ -1,203 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 Cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../ppi.h" -#include "../ui.h" -#include "../plat.h" -#include "pzx.h" -#include "cassette.h" - -typedef struct cassette_t -{ - uint8_t motor; /* Motor status */ - pzxfile_t pzx; - int cycles_last; /* Cycle count at last cassette poll */ - -} cassette_t; - -wchar_t cassettefn[256]; - -static cassette_t *st_cas; - - -#ifdef ENABLE_CASSETTE_LOG -int cassette_do_log = ENABLE_CASSETTE_LOG; - - -static void -cassette_log(const char *fmt, ...) -{ - va_list ap; - - if (cassette_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define cassette_log(fmt, ...) -#endif - - -/* The PCEM CPU uses IBM cycles (4.77MHz). PZX uses Spectrum cycles (3.5MHz) - * so scale accordingly. */ -static int32_t -pzx_cycles(int32_t pc) -{ - double d = pc; - - return (int32_t)(((d * 3.5) / 4.772728) + 0.5); -} - -void -cassette_eject(void) -{ - if (st_cas->pzx.input) { - pzx_close(&st_cas->pzx); - } - cassettefn[0] = 0; -} - -void -cassette_load(wchar_t *fn) -{ - FILE *fp; - unsigned char magic[8]; - - if (!fn) - return; - - fp = plat_fopen(fn, L"rb"); - if (!fp) { - /* Warn user? */ - cassette_log("Failed to open cassette input %s\n", fn); - return; - } - memset(magic, 0, sizeof(magic)); - fread(magic, 1, sizeof(magic), fp); - - /* Check for PZX signature. In due course support could be added for - * other formats like TZX */ - if (!memcmp(magic, "PZXT", 4)) { - wchar_t *result; - - result = pzx_open(&st_cas->pzx, fp); - - if (result) { - cassette_log("Failed to open %s as PZX: %s\n", - fn, result); - fclose(fp); - return; - } - wcscpy(cassettefn, fn); - } -} - - -uint8_t -cassette_input(void) -{ - int ticks; - - /* While motor is off, result is loopback */ - if (!st_cas->motor) - return ppispeakon; - /* If there is no tapefile open don't try to extract data */ - if (st_cas->pzx.input == NULL) - return 0; - /* Otherwise see how many ticks there have been since the last input */ - if (st_cas->cycles_last == -1) - st_cas->cycles_last = cycles; - if (cycles <= st_cas->cycles_last) - ticks = (st_cas->cycles_last - cycles); - else - ticks = (st_cas->cycles_last + (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed / 100) - cycles); - st_cas->cycles_last = cycles; - - return pzx_advance(&st_cas->pzx, pzx_cycles(ticks)); -} - - - -void -cassette_set_motor(uint8_t on) -{ - if (on && !st_cas->motor) { - cassette_log("Start cassette motor\n"); - st_cas->cycles_last = -1; - } - if (st_cas->motor && !on) { - cassette_log("Stop cassette motor\n"); - st_cas->cycles_last = -1; - } - st_cas->motor = on; -} - - -static void -*cassette_init(const device_t *info) -{ - cassette_t *cas = (cassette_t *)malloc(sizeof(cassette_t)); - memset(cas, 0, sizeof(cassette_t)); - pzx_init(&cas->pzx); - - st_cas = cas; - return cas; -} - - -static void -cassette_close(void *p) -{ - cassette_t *cas = (cassette_t *)p; - - pzx_close(&cas->pzx); - - free(cas); -} - - -const device_t cassette_device = { - "IBM PC 5150 Cassette", - 0, - 0, - cassette_init, - cassette_close, - NULL, - NULL, - NULL, - NULL -}; - diff --git a/src/cassette/cassette.h b/src/cassette/cassette.h deleted file mode 100644 index cf7712811..000000000 --- a/src/cassette/cassette.h +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -extern wchar_t cassettefn[256]; - -extern const device_t cassette_device; - -uint8_t cassette_input(void); -void cassette_set_motor(uint8_t on); -void cassette_eject(void); -void cassette_load(wchar_t *filename); diff --git a/src/cassette/pzx.c b/src/cassette/pzx.c deleted file mode 100644 index c7d16d36e..000000000 --- a/src/cassette/pzx.c +++ /dev/null @@ -1,414 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 Cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "../86box.h" -#include "../ui.h" -#include "pzx.h" - -/* This module is intended to abstract all the details of a PZX file and - * emit its contents as a bitstream in a form suitable for PCEM. Similar - * modules could be written to add support for other tape formats such as TZX, - * TAP or CSW. */ - - -#ifdef ENABLE_PZX_LOG -int pzx_do_log = ENABLE_PZX_LOG; - - -static void -pzx_log(const char *fmt, ...) -{ - va_list ap; - - if (pzx_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define pzx_log(fmt, ...) -#endif - -static uint32_t -peek2(uint8_t *data) -{ - return (((uint32_t)data[1]) << 8) | data[0]; -} - -static uint32_t -peek4(uint8_t *data) -{ - return (((uint32_t)data[3]) << 24) | - (((uint32_t)data[2]) << 16) | - (((uint32_t)data[1]) << 8) | data[0]; -} - -/* Cue up the next pulse definition from the current PULS block. */ -static void -pzx_parse_pulse(pzxfile_t *pzx) -{ - pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - if (pzx->puls_duration > 0x8000) { - pzx->puls_count = pzx->puls_duration & 0x7FFF; - pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - } - if (pzx->puls_duration >= 0x8000) { - pzx->puls_duration &= 0x7FFF; - pzx->puls_duration <<= 16; - pzx->puls_duration |= peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - } - if (!pzx->puls_count) pzx->puls_count = 1; -} - - -void -pzx_init(pzxfile_t *pzx) -{ - memset(pzx, 0, sizeof(pzxfile_t)); - pzx->state = PZX_CLOSED; -} - -/* Load the next block from a PZX-format file. - * - * Returns block if successful, NULL if end of file or error - * Caller must free the block with free(). */ -uint8_t -*pzx_load_block(FILE *fp) -{ - uint8_t block_header[8]; - uint8_t *block_data; - uint32_t block_len; - - /* The first 8 bytes of a PZX block are fixed: the first 4 give - * the ID, the second 4 the length (excluding the header itself) */ - if (fread(block_header, 1, 8, fp) < 8) - return NULL; /* EoF */ - - block_len = peek4(block_header + 4); - block_data = malloc(8 + block_len); - if (!block_data) return NULL; - memcpy(block_data, block_header, 8); - if (!block_len) { /* Block is only the header */ -/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ - return block_data; - } - if (fread(block_data + 8, 1, block_len, fp) < block_len) { - free(block_data); /* Unexpected EoF */ - return NULL; - } -/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ - return block_data; -} - - -/* Search the current file for PZX version headers and check they're all 1.x */ -static wchar_t -*pzx_check_version(FILE *fp) -{ - uint8_t *block; - static wchar_t message[80]; - - rewind(fp); - while ((block = pzx_load_block(fp))) { - if (!memcmp(block, "PZXT", 4)) { - pzx_log("PZX version %d.%d\n", block[8], block[9]); - if (block[8] != 1) { - swprintf(message, 80, L"Unsupported PZX version %d.%d\n", block[8], block[9]); - free(block); - return message; - } - } - free(block); - } - rewind(fp); - return NULL; -} - - -wchar_t -*pzx_open(pzxfile_t *pzx, FILE *fp) -{ - wchar_t *result; - - rewind(fp); - /* Check that this file is compatible */ - result = pzx_check_version(fp); - if (result) - return result; - - pzx->level = 0; - pzx->state = PZX_IDLE; - pzx->input = fp; - return NULL; -} - -void -pzx_close(pzxfile_t *pzx) -{ - if (pzx->input) { - fclose(pzx->input); - pzx->input = NULL; - } - if (pzx->curblock) { - free(pzx->curblock); - pzx->curblock = NULL; - } - pzx->state = PZX_CLOSED; -} - -/* Read the next block of type DATA, PAUS or PULS */ -int -pzx_next_block(pzxfile_t *pzx) -{ - long pos; - - pos = ftell(pzx->input); - while (pzx->state == PZX_IDLE) { - uint8_t *blk; - - /* In idle state there should be no current block. But - * make sure of that */ - if (pzx->curblock) { - free(pzx->curblock); - pzx->curblock = NULL; - } - - /* Load the next block */ - blk = pzx_load_block(pzx->input); - - /* If that didn't load we've reached the end of file; wrap to - * beginning. */ - if (!blk) { - rewind(pzx->input); - blk = pzx_load_block(pzx->input); - if (!blk) { /* Couldn't even load first block */ - pzx_close(pzx); - return 0; - } - /* Have we read the whole file and come back to where - * we were? */ - if (ftell(pzx->input) == pos) { - free(blk); - pzx_close(pzx); - return 0; - } - } - /* We have loaded the next block. What is it? */ - if (!memcmp(blk, "PULS", 4)) { - pzx->state = PZX_IN_PULS; - pzx->curblock = blk; - pzx->puls_len = 8 + peek4(blk + 4); - pzx->puls_ptr = 8; - pzx->puls_count = 0; - pzx->puls_remain = 0; - pzx->puls_duration = 0; - pzx->level = 0; - pzx_log("Beginning PULS block\n"); - } - else if (!memcmp(blk, "PAUS", 4)) { - pzx->state = PZX_IN_PAUS; - pzx->curblock = blk; - pzx->paus_remain = peek4(blk + 8); - pzx->level = (pzx->paus_remain >> 31); - pzx->paus_remain &= 0x7FFFFFFF; - pzx_log("Beginning PAUS block, duration=%d\n", - pzx->paus_remain); - } - else if (!memcmp(blk, "DATA", 4)) { - pzx->state = PZX_IN_DATA; - pzx->curblock = blk; - pzx->data_bits = peek4(blk + 8); - pzx->level = (pzx->data_bits >> 31); - pzx->data_bits &= 0x7FFFFFFF; - pzx->data_tail = peek2(blk + 12); - pzx->data_p0 = blk[14]; - pzx->data_p1 = blk[15]; - pzx->data_p = 0; - pzx->data_w = 16; - pzx->data_remain = 0; - pzx->data_ptr = 16 + 2 * (pzx->data_p0 + pzx->data_p1); - pzx->data_mask = 0x80; - pzx_log("Beginning DATA block, length=%d p0=%d p1=%d" - " data_ptr=%d\n", - pzx->data_bits, - pzx->data_p0, pzx->data_p1, - pzx->data_ptr); - } - } - return 1; -} - -static void -pzx_endblock(pzxfile_t *pzx) -{ - if (pzx->curblock) - free(pzx->curblock); - pzx->curblock = NULL; - pzx->state = PZX_IDLE; -} - -/* PAUS is easy - just run the timer down */ -static int -pzx_advance_paus(pzxfile_t *pzx, int time) -{ - if (pzx->paus_remain > time) { - pzx->paus_remain -= time; - return 0; - } - time -= pzx->paus_remain; - pzx_endblock(pzx); - return time; -} - -static int -pzx_advance_puls(pzxfile_t *pzx, int time) -{ - /* At the start of a pulse sequence? */ - if (pzx->puls_count == 0) { - pzx_parse_pulse(pzx); - pzx->puls_remain = pzx->puls_duration; - } - /* Does sample trigger a pulse change? If not, that's easy. */ - if (time < pzx->puls_remain) { - pzx->puls_remain -= time; - return 0; - } - /* Sample does trigger a pulse change */ - time -= pzx->puls_remain; - /* If there's another pulse in the current sequence, that's - * straightforward; just flip the level and continue */ - --pzx->puls_count; - pzx->level = !pzx->level; - if (pzx->puls_count) { - pzx->puls_remain = pzx->puls_duration; - return time; - } - /* If we've reached the end of the pulse sequence, there may be - * another one */ - if (pzx->puls_ptr < pzx->puls_len) { - return time; - } - /* If there isn't another one, it's the end of the block */ - pzx_endblock(pzx); - return time; -} - -/* Decode a DATA block */ -static int -pzx_advance_data(pzxfile_t *pzx, int time) -{ - uint8_t bit; - - /* Reached end of data? */ - if (pzx->data_bits == 0) { - /* Time interval is covered by the tail bit */ - if (pzx->data_tail > time) { - pzx->data_tail -= time; - return 0; - } - /* Have run out of block */ - time -= pzx->data_tail; - pzx_endblock(pzx); - return time; - } - /* No more time remaining on the current bit? */ - if (pzx->data_p < 1 && !pzx->data_remain) { - bit = pzx->curblock[pzx->data_ptr] & pzx->data_mask; - pzx->data_mask >>= 1; - if (!pzx->data_mask) { - pzx->data_mask = 0x80; - ++pzx->data_ptr; - } - --pzx->data_bits; - - if (bit) { - pzx->data_p = pzx->data_p1; - pzx->data_w = 16 + 2 * pzx->data_p0; - pzx->data_remain = 0; - } else { - pzx->data_p = pzx->data_p0; - pzx->data_w = 16; - pzx->data_remain = 0; - } - } - /* See if we've started processing the current waveform. If not, - * load its first element (assuming that there is one) */ - if (!pzx->data_remain) { - if (pzx->data_p) { - pzx->data_remain = peek2(pzx->curblock + pzx->data_w); - pzx->data_w += 2; - pzx->data_p--; - } - } - if (pzx->data_remain > time) { - /* Time advance is contained within current wave */ - pzx->data_remain -= time; - return 0; - } else { /* Move on to next element of wave / next bit / next block */ - time -= pzx->data_remain; - pzx->data_remain = 0; - pzx->level = !pzx->level; - } - - return time; -} - -int -pzx_advance(pzxfile_t *pzx, int time) -{ - if (pzx->state == PZX_CLOSED) - return 0; /* No tape loaded */ - - while (time) { - switch (pzx->state) - { - case PZX_IDLE: - if (!pzx_next_block(pzx)) return 0; - break; - case PZX_IN_PULS: - time = pzx_advance_puls(pzx, time); - break; - case PZX_IN_PAUS: - time = pzx_advance_paus(pzx, time); - break; - case PZX_IN_DATA: - time = pzx_advance_data(pzx, time); - break; - } - } - return pzx->level; -} - - - diff --git a/src/cassette/pzx.h b/src/cassette/pzx.h deleted file mode 100644 index a642a0688..000000000 --- a/src/cassette/pzx.h +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************ - - PCEM: IBM 5150 cassette support - - Copyright (C) 2019 John Elliott - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*************************************************************************/ - -typedef enum -{ - PZX_CLOSED, /* File is not open */ - PZX_IDLE, /* File is open, no block loaded */ - PZX_IN_PULS, /* File is open, current block is a PULS block */ - PZX_IN_DATA, /* File is open, current block is a DATA block */ - PZX_IN_PAUS, /* File is open, current block is a PAUS block */ -} PZX_STATE; - - -typedef struct pzxfile_t -{ - FILE *input; /* Input PZX file */ - uint8_t *curblock; /* Currently-loaded block, if any */ - int level; /* Current signal level */ - PZX_STATE state; /* State machine current status */ -/* State variables for PULS */ - uint32_t puls_ptr; /* Pointer within PULS block */ - uint32_t puls_len; /* Length of PULS block */ - uint32_t puls_count; /* Count of pulses */ - uint32_t puls_duration; /* Duration of each pulse */ - uint32_t puls_remain; /* Time remaining in this pulse */ -/* State variables for PAUS */ - uint32_t paus_remain; /* Time remaining in this pause */ -/* State variables for DATA */ - uint32_t data_ptr; /* Pointer within DATA block */ - uint32_t data_bits; /* Count of bits */ - uint16_t data_tail; /* Length of pulse after last bit */ - uint8_t data_mask; /* Mask for current bit */ - uint8_t data_p0; /* Length of 0 encoding */ - uint8_t data_p1; /* Length of 1 encoding */ - int data_p; /* Current sequence being emitted */ - uint32_t data_w; /* Current waveform */ - uint32_t data_remain; /* Current data pulse time remaining */ -} pzxfile_t; - -uint8_t *pzx_load_block(FILE *fp); - -/* Initialise structure */ -void pzx_init(pzxfile_t *pzx); - -/* Open file for input */ -wchar_t *pzx_open(pzxfile_t *pzx, FILE *fp); - -/* Close file */ -void pzx_close(pzxfile_t *pzx); - -/* Advance by 'time' samples (3.5MHz sample rate) and return current state */ -int pzx_advance(pzxfile_t *pzx, int time); diff --git a/src/cdrom.d b/src/cdrom.d new file mode 100644 index 000000000..4e9a5061d --- /dev/null +++ b/src/cdrom.d @@ -0,0 +1,2 @@ +cdrom.o: cdrom/cdrom.c 86box.h config.h cdrom/cdrom.h cdrom/cdrom_image.h \ + plat.h lang/language.h sound/sound.h diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 6c19233a7..00262bcf5 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -22,12 +22,12 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" +#include "86box.h" +#include "config.h" #include "cdrom.h" #include "cdrom_image.h" -#include "../plat.h" -#include "../sound/sound.h" +#include "plat.h" +#include "sound.h" /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 84dff1f98..2a4c7b30c 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -29,10 +29,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../plat.h" -#include "../scsi/scsi_device.h" +#include "86box.h" +#include "config.h" +#include "plat.h" +#include "scsi_device.h" #include "cdrom_image_backend.h" #include "cdrom.h" #include "cdrom_image.h" diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 556c0e954..c85739b6c 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -35,8 +35,8 @@ #endif #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "cdrom_image_backend.h" @@ -190,6 +190,9 @@ track_file_close(track_t *trk) if (trk->file == NULL) return; + if (trk->file->close == NULL) + return; + trk->file->close(trk->file); trk->file = NULL; } @@ -209,10 +212,12 @@ cdi_clear_tracks(cd_img_t *cdi) for (i = 0; i < cdi->tracks_num; i++) { cur = &cdi->tracks[i]; + /* Make sure we do not attempt to close a NULL file. */ if (cur->file != last) { - track_file_close(cur); last = cur->file; - } + track_file_close(cur); + } else + cur->file = NULL; } /* Now free the array. */ diff --git a/src/cdrom_image.d b/src/cdrom_image.d new file mode 100644 index 000000000..f7cbf445f --- /dev/null +++ b/src/cdrom_image.d @@ -0,0 +1,3 @@ +cdrom_image.o: cdrom/cdrom_image.c 86box.h config.h plat.h \ + lang/language.h scsi/scsi_device.h cdrom/cdrom_image_backend.h \ + cdrom/cdrom.h cdrom/cdrom_image.h diff --git a/src/cdrom_image_backend.d b/src/cdrom_image_backend.d new file mode 100644 index 000000000..e31acdba5 --- /dev/null +++ b/src/cdrom_image_backend.d @@ -0,0 +1,2 @@ +cdrom_image_backend.o: cdrom/cdrom_image_backend.c 86box.h plat.h \ + lang/language.h cdrom/cdrom_image_backend.h diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 1df0fec34..686301c24 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -20,19 +20,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../device.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../mouse.h" -#include "../port_92.h" -#include "../sio.h" -#include "../disk/hdc.h" -#include "../video/video.h" -#include "../video/vid_ht216.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "device.h" +#include "keyboard.h" +#include "86box_io.h" +#include "mem.h" +#include "mouse.h" +#include "port_92.h" +#include "sio.h" +#include "hdc.h" +#include "video.h" #include "chipset.h" diff --git a/src/chipset/acer_m3a.c b/src/chipset/acer_m3a.c index 0d8ab2052..43c19d6f1 100644 --- a/src/chipset/acer_m3a.c +++ b/src/chipset/acer_m3a.c @@ -20,13 +20,13 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" #include "chipset.h" diff --git a/src/chipset/ali1429.c b/src/chipset/ali1429.c index 5d5b4bd83..2f6b8cad1 100644 --- a/src/chipset/ali1429.c +++ b/src/chipset/ali1429.c @@ -21,19 +21,19 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../mem.h" -#include "../device.h" -#include "../keyboard.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../timer.h" -#include "../port_92.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "mem.h" +#include "device.h" +#include "keyboard.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "timer.h" +#include "port_92.h" #include "chipset.h" diff --git a/src/chipset/chipset.h b/src/chipset/chipset.h index b78f177c5..025bf16a8 100644 --- a/src/chipset/chipset.h +++ b/src/chipset/chipset.h @@ -8,7 +8,7 @@ * * Handling of the emulated chipsets. * - * Version: @(#)machine.h 1.0.1 2020/01/14 + * Version: @(#)machine.h 1.0.2 2020/01/24 * * Authors: Miran Grca, * @@ -33,14 +33,17 @@ extern const device_t headland_386_device; /* Intel 4x0xX */ extern const device_t i420tx_device; +extern const device_t i420zx_device; extern const device_t i430lx_device; extern const device_t i430nx_device; extern const device_t i430fx_device; extern const device_t i430fx_pb640_device; extern const device_t i430hx_device; extern const device_t i430vx_device; +extern const device_t i430tx_device; #if defined(DEV_BRANCH) && defined(USE_I686) extern const device_t i440fx_device; +extern const device_t i440bx_device; #endif /* NEAT */ diff --git a/src/chipset/headland.c b/src/chipset/headland.c index cbd52cfb1..d3f1f4081 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -25,18 +25,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#include "../timer.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../keyboard.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../port_92.h" +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "timer.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "keyboard.h" +#include "fdd.h" +#include "fdc.h" +#include "port_92.h" #include "chipset.h" diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index cf2901146..7d4983e44 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -8,51 +8,64 @@ * * Implementation of the Intel PCISet chips from 420TX to 440FX. * - * Version: @(#)intel_4x0.c 1.0.2 2019/10/21 + * Version: @(#)intel_4x0.c 1.0.3 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2019 Miran Grca. + * Copyright 2019,2020 Miran Grca. */ #include #include #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" #include "chipset.h" enum { INTEL_420TX, + INTEL_420ZX, INTEL_430LX, INTEL_430NX, INTEL_430FX, INTEL_430FX_PB640, INTEL_430HX, - INTEL_430VX + INTEL_430VX, + INTEL_430TX #if defined(DEV_BRANCH) && defined(USE_I686) - ,INTEL_440FX + ,INTEL_440FX, + INTEL_440BX #endif }; typedef struct { +#if defined(DEV_BRANCH) && defined(USE_I686) + uint8_t pm2_cntrl, max_func; + uint8_t regs[2][256], regs_locked[2][256]; +#else + uint8_t pm2_cntrl; uint8_t regs[256]; +#endif int type; } i4x0_t; + + static void i4x0_map(uint32_t addr, uint32_t size, int state) { + // pclog("i4x0_map(%08X, %08X, %02X)\n", addr, size, state); + switch (state & 3) { case 0: mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); @@ -71,116 +84,872 @@ i4x0_map(uint32_t addr, uint32_t size, int state) } +#if defined(DEV_BRANCH) && defined(USE_I686) +static void +i4x0_mask_bar(uint8_t *regs) +{ + uint32_t bar; + + bar = (regs[0x13] << 24) | (regs[0x12] << 16); + bar &= (((uint32_t) regs[0xb4] << 22) | 0xf0000000); + regs[0x12] = (bar >> 16) & 0xff; + regs[0x13] = (bar >> 24) & 0xff; +} +#endif + + +static uint8_t +pm2_cntrl_read(uint16_t addr, void *p) +{ + i4x0_t *dev = (i4x0_t *) p; + + // pclog("PM2_CTL read: %02X\n", dev->pm2_cntrl & 0x01); + return dev->pm2_cntrl & 0x01; +} + + +static void +pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) +{ + i4x0_t *dev = (i4x0_t *) p; + + // pclog("PM2_CTL write: %02X\n", val); + dev->pm2_cntrl = val & 0x01; +} + + static void i4x0_write(int func, int addr, uint8_t val, void *priv) { i4x0_t *dev = (i4x0_t *) priv; +#if defined(DEV_BRANCH) && defined(USE_I686) + uint8_t *regs = (uint8_t *) dev->regs[func]; + uint8_t *regs_l = (uint8_t *) dev->regs_locked[func]; + int i; +#else + uint8_t *regs = (uint8_t *) dev->regs; +#endif - if (func) +#if defined(DEV_BRANCH) && defined(USE_I686) + if (func > dev->max_func) { +#else + if (func > 0) { +#endif + // pclog("invalid write %02X to %02X:%02X\n", val, func, addr); return; + } + + // pclog("write %02X to %02X:%02X\n", val, func, addr); if ((addr >= 0x10) && (addr < 0x4f)) return; - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0c: case 0x0e: - return; - + if (func == 0) switch (addr) { case 0x04: /*Command register*/ - if (dev->type >= INTEL_430FX) { - if (dev->type == INTEL_430FX_PB640) - val &= 0x06; - else - val &= 0x02; - } else - val &= 0x42; - val |= 0x04; + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: +#endif + default: + regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42); + break; + case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02); + break; + } break; case 0x05: - if (dev->type >= INTEL_430FX) - val = 0; - else - val &= 0x01; - break; - - case 0x06: /*Status*/ - val = 0; + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: case INTEL_440BX: +#endif + regs[0x05] = (regs[0x05] & ~0x01) | (val & 0x01); + break; + } break; case 0x07: - if (dev->type >= INTEL_430HX) { - val &= 0x80; - val |= 0x02; - } else { - val = 0x02; - if (dev->type == INTEL_430FX_PB640) - val |= 0x20; + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX: + default: + regs[0x07] &= ~(val & 0x70); + break; + case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430VX: case INTEL_430TX: + regs[0x07] &= ~(val & 0x30); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x07] &= ~(val & 0xf9); + break; + case INTEL_440BX: + regs[0x07] &= ~(val & 0xf0); + break; +#endif } break; - - case 0x52: /*Cache Control Register*/ -#if defined(DEV_BRANCH) && defined(USE_I686) - if (dev->type < INTEL_440FX) { -#endif - cpu_cache_ext_enabled = (val & 0x01); - cpu_update_waitstates(); -#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x0d: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: + regs[0x0d] = (val & 0xf0); + break; + default: + regs[0x0d] = (val & 0xf8); + break; } -#endif break; - - case 0x59: /*PAM0*/ - if ((dev->regs[0x59] ^ val) & 0xf0) { + case 0x0f: + switch (dev->type) { + case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: + regs[0x0f] = (val & 0x40); + break; + } + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x12: + switch (dev->type) { + case INTEL_440BX: + regs[0x12] = (val & 0xc0); + i4x0_mask_bar(regs); + break; + } + break; + case 0x13: + switch (dev->type) { + case INTEL_440BX: + regs[0x13] = val; + i4x0_mask_bar(regs); + break; + } + break; + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + switch (dev->type) { + case INTEL_440BX: + if (!regs_l[addr]) { + regs[addr] = val; + regs_l[addr] = 1; + } + break; + } + break; +#endif + case 0x4f: + switch (dev->type) { + case INTEL_430HX: + regs[0x4f] = (val & 0x84); + break; + case INTEL_430VX: + regs[0x4f] = (val & 0x94); + break; + case INTEL_430TX: + regs[0x4f] = (val & 0x80); + break; + } + break; + case 0x50: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: default: + regs[0x50] = (val & 0xe5); + break; + case INTEL_430NX: + regs[0x50] = (val & 0xe7); + break; + case INTEL_430FX: case INTEL_430FX_PB640: + regs[0x50] = (val & 0xef); + break; + case INTEL_430HX: + regs[0x50] = (val & 0xf7); + break; + case INTEL_430VX: case INTEL_430TX: + regs[0x50] = (val & 0x08); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x50] = (val & 0xf4); + break; + case INTEL_440BX: + regs[0x50] = (regs[0x50] & 0x14) | (val & 0xeb); + break; +#endif + } + break; + case 0x51: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: + regs[0x51] = (val & 0xc0); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x51] = (val & 0xc3); + break; + case INTEL_440BX: + regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f); + break; +#endif + } + break; + case 0x52: /* Cache Control Register */ + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430VX: case INTEL_430TX: + default: + regs[0x52] = (val & 0xfb); + break; + case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + regs[0x52] = val; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: + regs[0x52] = val & 0x07; + break; +#endif + } + break; + case 0x53: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + regs[0x53] = val & 0x0b; + break; + case INTEL_430NX: + regs[0x53] = val & 0x0a; + break; + case INTEL_430VX: case INTEL_430TX: + regs[0x53] = val & 0x3f; + break; + } + break; + case 0x54: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[0x54] = val & 0x07; + break; + case INTEL_430VX: + regs[0x54] = val & 0xd8; + break; + case INTEL_430TX: + regs[0x54] = val & 0xfa; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x54] = val & 0x82; + break; +#endif + } + break; + case 0x55: + switch (dev->type) { + case INTEL_430VX: case INTEL_430TX: + regs[0x55] = val & 0x01; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x55] = val; + break; +#endif + } + break; + case 0x56: + switch (dev->type) { + case INTEL_430HX: + regs[0x56] = val & 0x1f; + break; + case INTEL_430VX: + regs[0x56] = val & 0x77; + break; + case INTEL_430TX: + regs[0x56] = val & 0x76; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x56] = val; + break; +#endif + } + break; + case 0x57: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: default: + regs[0x57] = val & 0x3f; + break; + case INTEL_430NX: + regs[0x57] = val; + break; + case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430HX: case INTEL_430VX: + regs[0x57] = val & 0xcf; + break; + case INTEL_430TX: + regs[0x57] = val & 0xdf; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x57] = val & 0x77; + break; + case INTEL_440BX: + regs[0x57] = val & 0x3f; + break; +#endif + } + break; + case 0x58: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: default: + regs[0x58] = val & 0x01; + break; + case INTEL_430NX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: +#endif + regs[0x58] = val & 0x03; + break; + case INTEL_430FX: case INTEL_430FX_PB640: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: +#endif + regs[0x58] = val & 0x7f; + break; + case INTEL_430HX: case INTEL_430VX: + regs[0x57] = val; + break; + case INTEL_430TX: + regs[0x57] = val & 0x7b; + break; + } + break; + case 0x59: /* PAM0 */ + if (dev->type <= INTEL_430NX) { + if ((regs[0x59] ^ val) & 0x0f) + i4x0_map(0x80000, 0x20000, val & 0x0f); + } + if ((regs[0x59] ^ val) & 0xf0) { i4x0_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } + if (dev->type > INTEL_430NX) + regs[0x59] = val & 0x70; + else + regs[0x59] = val & 0x77; break; - case 0x5a: /*PAM1*/ - if ((dev->regs[0x5a] ^ val) & 0x0f) + case 0x5a: /* PAM1 */ + if ((regs[0x5a] ^ val) & 0x0f) i4x0_map(0xc0000, 0x04000, val & 0xf); - if ((dev->regs[0x5a] ^ val) & 0xf0) + if ((regs[0x5a] ^ val) & 0xf0) i4x0_map(0xc4000, 0x04000, val >> 4); + regs[0x5a] = val & 0x77; break; - case 0x5b: /*PAM2*/ - if ((dev->regs[0x5b] ^ val) & 0x0f) + case 0x5b: /*PAM2 */ + if ((regs[0x5b] ^ val) & 0x0f) i4x0_map(0xc8000, 0x04000, val & 0xf); - if ((dev->regs[0x5b] ^ val) & 0xf0) + if ((regs[0x5b] ^ val) & 0xf0) i4x0_map(0xcc000, 0x04000, val >> 4); + regs[0x5b] = val & 0x77; break; - case 0x5c: /*PAM3*/ - if ((dev->regs[0x5c] ^ val) & 0x0f) + case 0x5c: /*PAM3 */ + if ((regs[0x5c] ^ val) & 0x0f) i4x0_map(0xd0000, 0x04000, val & 0xf); - if ((dev->regs[0x5c] ^ val) & 0xf0) + if ((regs[0x5c] ^ val) & 0xf0) i4x0_map(0xd4000, 0x04000, val >> 4); + regs[0x5c] = val & 0x77; break; - case 0x5d: /*PAM4*/ - if ((dev->regs[0x5d] ^ val) & 0x0f) + case 0x5d: /* PAM4 */ + if ((regs[0x5d] ^ val) & 0x0f) i4x0_map(0xd8000, 0x04000, val & 0xf); - if ((dev->regs[0x5d] ^ val) & 0xf0) + if ((regs[0x5d] ^ val) & 0xf0) i4x0_map(0xdc000, 0x04000, val >> 4); + regs[0x5d] = val & 0x77; break; - case 0x5e: /*PAM5*/ - if ((dev->regs[0x5e] ^ val) & 0x0f) + case 0x5e: /* PAM5 */ + if ((regs[0x5e] ^ val) & 0x0f) i4x0_map(0xe0000, 0x04000, val & 0xf); - if ((dev->regs[0x5e] ^ val) & 0xf0) + if ((regs[0x5e] ^ val) & 0xf0) i4x0_map(0xe4000, 0x04000, val >> 4); + regs[0x5e] = val & 0x77; break; - case 0x5f: /*PAM6*/ - if ((dev->regs[0x5f] ^ val) & 0x0f) + case 0x5f: /* PAM6 */ + if ((regs[0x5f] ^ val) & 0x0f) i4x0_map(0xe8000, 0x04000, val & 0xf); - if ((dev->regs[0x5f] ^ val) & 0xf0) + if ((regs[0x5f] ^ val) & 0xf0) i4x0_map(0xec000, 0x04000, val >> 4); + regs[0x5f] = val & 0x77; break; - case 0x72: /*SMRAM*/ - if ((dev->type >= INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x48)) - i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); - else if ((dev->type < INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x20)) - i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0); + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: case INTEL_440BX: +#endif + default: + regs[addr] = val; + break; + case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430VX: + regs[addr] = val/* & 0x3f*/; + break; + case INTEL_430TX: + regs[addr] = val & 0x7f; + break; + } break; + case 0x65: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: case INTEL_440BX: +#endif + regs[addr] = val; + break; + case INTEL_430VX: + regs[addr] = val & 0x3f; + break; + case INTEL_430TX: + regs[addr] = val & 0x7f; + break; + } + break; + case 0x66: + switch (dev->type) { + case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: case INTEL_440BX: +#endif + regs[addr] = val; + break; + } + break; + case 0x67: + switch (dev->type) { + case INTEL_430NX: case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: case INTEL_440BX: +#endif + regs[addr] = val; + break; + case INTEL_430VX: + regs[addr] = val & 0x11; + break; + case INTEL_430TX: + regs[addr] = val & 0xb7; + break; + } + break; + case 0x68: + switch (dev->type) { + case INTEL_430NX: case INTEL_430HX: + case INTEL_430VX: case INTEL_430TX: + regs[0x68] = val; + break; + case INTEL_430FX: case INTEL_430FX_PB640: + regs[0x68] = val & 0x1f; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x68] = val & 0xc0; + break; + case INTEL_440BX: + regs[0x68] = (regs[0x68] & 0x38) | (val & 0xc7); + break; +#endif + } + break; + case 0x69: + switch (dev->type) { + case INTEL_430NX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: +#endif + regs[0x69] = val; + break; + case INTEL_430VX: + regs[0x69] = val & 0x07; + break; + } + break; + case 0x6a: case 0x6b: + switch (dev->type) { + case INTEL_430NX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: +#endif + regs[addr] = val; + break; + } + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x6c: case 0x6d: case 0x6e: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + break; + } + break; +#endif + case 0x70: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + regs[addr] = val & 0xc7; + break; + case INTEL_430NX: + regs[addr] = val; + break; + case INTEL_430VX: case INTEL_430TX: + regs[addr] = val & 0xfc; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[addr] = val & 0xf8; + break; +#endif + } + break; + case 0x71: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: + regs[addr] = val & 0x4d; + break; + case INTEL_430TX: + regs[addr] = val; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[addr] = val & 0x1f; + break; +#endif + } + break; + case 0x72: /* SMRAM */ + if (dev->type >= INTEL_430FX) { + if ((regs[0x72] ^ val) & 0x48) + i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); + regs[0x72] = val & 0x7f; + } else { + if ((regs[0x72] ^ val) & 0x20) + i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0); + regs[0x72] = val & 0x3f; + } + break; + case 0x73: + switch (dev->type) { + case INTEL_430VX: + regs[0x73] = val & 0x03; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: + regs[0x73] = val; + break; +#endif + } + break; + case 0x74: + switch (dev->type) { + case INTEL_430VX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: +#endif + regs[0x74] = val; + break; + } + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x75: case 0x76: + case 0x7b: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + } + break; + case 0x77: + switch (dev->type) { + case INTEL_440BX: + regs[0x77] = val & 0x03; + } + break; +#endif + case 0x78: + switch (dev->type) { + case INTEL_430VX: + regs[0x78] = val & 0xcf; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: + regs[0x78] = val & 0x0f; + break; +#endif + } + break; + case 0x79: + switch (dev->type) { + case INTEL_430TX: + regs[0x79] = val & 0x74; + io_removehandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + if (val & 0x40) + io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + // pclog("430TX: PM2_CTL now %sabled\n", (val & 0x40) ? "en" : "dis"); + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: + regs[0x79] = val; + break; +#endif + } + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x7a: + switch (dev->type) { + case INTEL_440BX: + regs[0x7a] = (regs[0x7a] & 0x0a) | (val & 0xf5); + io_removehandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + if (val & 0x40) + io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + // pclog("440BX: PM2_CTL now %sabled\n", (val & 0x40) ? "en" : "dis"); + break; + } + break; +#endif + case 0x7c: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[0x7c] = val & 0x8f; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440BX: + regs[0x7c] = val & 0x1f; + break; +#endif + } + case 0x7d: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[0x7c] = val & 0x32; + break; + } + case 0x7e: case 0x7f: + switch (dev->type) { + case INTEL_420TX: case INTEL_420ZX: + case INTEL_430LX: case INTEL_430NX: + regs[addr] = val; + break; + } +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x80: + switch (dev->type) { + case INTEL_440BX: + regs[0x80] &= ~(val & 0x03); + break; + } + break; +#endif + case 0x90: + switch (dev->type) { + case INTEL_430HX: + regs[0x80] = val & 0x87; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + regs[0x80] = val & 0x1b; + break; + case INTEL_440BX: + regs[0x7c] = val; + break; +#endif + } + break; + case 0x91: + switch (dev->type) { + case INTEL_430HX: +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: case INTEL_440BX: +#endif + regs[0x91] &= ~(val & 0x11); + break; + } + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case 0x92: + switch (dev->type) { + case INTEL_440BX: + regs[0x92] &= ~(val & 0x1f); + break; + } + break; + case 0x93: + switch (dev->type) { + case INTEL_440FX: + regs[0x93] = (val & 0x0f); + trc_write(0x0093, val & 0x06, NULL); + break; + } + break; + case 0xa8: case 0xa9: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = (val & 0x03); + break; + } + break; + case 0xb0: + switch (dev->type) { + case INTEL_440BX: + regs[0xb0] = (val & 0x80); + break; + } + break; + case 0xb1: + switch (dev->type) { + case INTEL_440BX: + regs[0xb1] = (val & 0xa0); + break; + } + break; + case 0xb4: + switch (dev->type) { + case INTEL_440BX: + regs[0xb4] = (val & 0x3f); + i4x0_mask_bar(regs); + break; + } + break; + case 0xb9: + switch (dev->type) { + case INTEL_440BX: + regs[0xb9] = (val & 0xf0); + break; + } + break; + case 0xba: case 0xbb: case 0xca: case 0xcb: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + break; + } + break; + case 0xcc: + switch (dev->type) { + case INTEL_440BX: + regs[0xcc] = (val & 0x7f); + break; + } + break; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: + case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: + switch (dev->type) { + case INTEL_440BX: + if (!regs_l[addr]) + regs[addr] = val; + break; + } + break; + case 0xe5: case 0xed: + switch (dev->type) { + case INTEL_440BX: + if (!regs_l[addr]) + regs[addr] = (val & 0x3f); + break; + } + break; + case 0xe7: + switch (dev->type) { + case INTEL_440BX: + regs[0xe7] = 0x80; + for (i = 0; i < 16; i++) + regs_l[0xe0 + i] = !!(val & 0x80); + if (!regs_l[0xe7]) { + regs[0xe7] |= (val & 0x7f); + } + break; + } + break; + case 0xf0: + switch (dev->type) { + case INTEL_440BX: + regs[0xf0] = (val & 0xc0); + break; + } + break; + case 0xf1: + switch (dev->type) { + case INTEL_440BX: + regs[0xf1] = (val & 0x03); + break; + } + break; + } else if (func == 1) switch (addr) { + case 0x04: + switch (dev->type) { + case INTEL_440BX: + regs[0x04] = (val & 0x1f); + break; + } + break; + case 0x05: + switch (dev->type) { + case INTEL_440BX: + regs[0x05] = (val & 0x01); + break; + } + break; + case 0x0d: case 0x1b: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = (val & 0xf8); + break; + } + break; + case 0x19: case 0x1a: + case 0x21: case 0x23: + case 0x25: case 0x27: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = val; + break; + } + break; + case 0x1c: case 0x1d: + case 0x20: case 0x22: + case 0x24: case 0x26: + switch (dev->type) { + case INTEL_440BX: + regs[addr] = (val & 0xf0); + break; + } + break; + case 0x1f: + switch (dev->type) { + case INTEL_440BX: + regs[0x1f] &= ~(val & 0xf0); + break; + } + break; + case 0x3e: + switch (dev->type) { + case INTEL_440BX: + regs[0x3e] = (val & 0xed); + break; + } + break; +#endif } - - dev->regs[addr] = val; } @@ -188,22 +957,62 @@ static uint8_t i4x0_read(int func, int addr, void *priv) { i4x0_t *dev = (i4x0_t *) priv; + uint8_t ret = 0xff; +#if defined(DEV_BRANCH) && defined(USE_I686) + uint8_t *regs = (uint8_t *) dev->regs[func]; +#else + uint8_t *regs = (uint8_t *) dev->regs; +#endif - if (func) - return 0xff; +#if defined(DEV_BRANCH) && defined(USE_I686) + if (func > dev->max_func) { +#else + if (func > 0) { +#endif + ret = 0xff; + // pclog("invalid read %02X from %02X:%02X\n", ret, func, addr); + } else { + ret = regs[addr]; +#if defined(DEV_BRANCH) && defined(USE_I686) + /* Special behavior for 440FX register 0x93 which is basically TRC in PCI space + with the addition of bits 3 and 0. */ + if ((func == 0) && (addr == 0x93) && (dev->type == INTEL_440FX)) + ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06); +#endif + // pclog("read %02X from %02X:%02X\n", ret, func, addr); + } - return dev->regs[addr]; + return ret; } static void i4x0_reset(void *priv) { - i4x0_t *i4x0 = (i4x0_t *)priv; + i4x0_t *dev = (i4x0_t *)priv; + int i; - i4x0_write(0, 0x59, 0x00, priv); - if (i4x0->type >= INTEL_430FX) + if (dev->type >= INTEL_430FX) + i4x0_write(0, 0x59, 0x00, priv); + else + i4x0_write(0, 0x59, 0x0f, priv); + + for (i = 0; i < 6; i++) + i4x0_write(0, 0x5a + i, 0x00, priv); + + if (dev->type >= INTEL_430FX) i4x0_write(0, 0x72, 0x02, priv); + else + i4x0_write(0, 0x72, 0x00, priv); + +#if defined(DEV_BRANCH) && defined(USE_I686) + if (dev->type == INTEL_440BX) { + for (i = 0; i <= dev->max_func; i++) + memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t)); + } +#endif + + smbase = 0xa0000; } @@ -219,114 +1028,232 @@ i4x0_close(void *p) static void *i4x0_init(const device_t *info) { - i4x0_t *i4x0 = (i4x0_t *) malloc(sizeof(i4x0_t)); - memset(i4x0, 0, sizeof(i4x0_t)); + i4x0_t *dev = (i4x0_t *) malloc(sizeof(i4x0_t)); + uint8_t *regs; - i4x0->type = info->local; + memset(dev, 0, sizeof(i4x0_t)); - i4x0->regs[0x00] = 0x86; i4x0->regs[0x01] = 0x80; /*Intel*/ - switch(i4x0->type) { + dev->type = info->local & 0xff; + +#if defined(DEV_BRANCH) && defined(USE_I686) + regs = (uint8_t *) dev->regs[0]; +#else + regs = (uint8_t *) dev->regs; +#endif + + // This is off by default and has to be moved to the appropriate register handling. + // io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev); + + regs[0x00] = 0x86; regs[0x01] = 0x80; /*Intel*/ + + switch (dev->type) { case INTEL_420TX: - i4x0->regs[0x02] = 0x83; i4x0->regs[0x03] = 0x04; /*82424TX/ZX*/ - i4x0->regs[0x08] = 0x03; /*A3 stepping*/ - i4x0->regs[0x50] = 0x80; - i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + case INTEL_420ZX: + regs[0x02] = 0x83; regs[0x03] = 0x04; /* 82424TX/ZX */ + regs[0x06] = 0x40; + regs[0x08] = (dev->type == INTEL_420ZX) ? 0x01 : 0x00; + regs[0x0d] = 0x20; + if (is486sx) + regs[0x50] = 0x20; + else if (is486sx2) + regs[0x50] = 0x60; /* Guess based on the SX, DX, and DX2 values. */ + else if (is486dx || isdx4) + regs[0x50] = 0x00; + else if (is486dx2) + regs[0x50] = 0x40; + else + regs[0x50] = 0x80; /* Pentium OverDrive. */ + if (cpu_busspeed <= 25000000) + regs[0x50] |= 0x01; + else if ((cpu_busspeed > 25000000) && (cpu_busspeed <= 30000000)) + regs[0x50] |= 0x02; + else if ((cpu_busspeed > 30000000) && (cpu_busspeed <= 33333333)) + regs[0x50] |= 0x03; + regs[0x51] = 0x80; + regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + regs[0x57] = 0x31; + regs[0x59] = 0x0f; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; break; case INTEL_430LX: - i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/ - i4x0->regs[0x08] = 0x03; /*A3 stepping*/ - i4x0->regs[0x50] = 0x80; - i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ + regs[0x06] = 0x40; + regs[0x08] = 0x03; + regs[0x0d] = 0x20; + regs[0x50] = 0x82; + if (cpu_busspeed <= 60000000) + regs[0x50] |= 0x00; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x50] |= 0x01; + regs[0x51] = 0x80; + regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + regs[0x57] = 0x31; + regs[0x59] = 0x0f; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; break; case INTEL_430NX: - i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/ - i4x0->regs[0x08] = 0x10; /*A0 stepping*/ - i4x0->regs[0x50] = 0xA0; - i4x0->regs[0x52] = 0x44; /*256kb PLB cache*/ - i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02; + regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ + regs[0x06] = 0x40; + regs[0x08] = 0x11; + regs[0x0d] = 0x20; + regs[0x50] = 0x80; + if (cpu_busspeed <= 50000000) + regs[0x50] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x50] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x50] |= 0x03; + regs[0x51] = 0x80; + regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */ + regs[0x57] = 0x31; + regs[0x59] = 0x0f; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; break; - case INTEL_430FX: case INTEL_430FX_PB640: - i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/ - if (i4x0->type == INTEL_430FX_PB640) - i4x0->regs[0x08] = 0x02; /*???? stepping*/ - else - i4x0->regs[0x08] = 0x00; /*A0 stepping*/ - i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + regs[0x08] = 0x02; + /* FALLTHROUGH */ + case INTEL_430FX: + regs[0x02] = 0x2d; regs[0x03] = 0x12; /* SB82437FX-66 */ + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + if (cpu_busspeed <= 50000000) + regs[0x57] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x57] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x57] |= 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; + regs[0x72] = 0x02; break; case INTEL_430HX: - i4x0->regs[0x02] = 0x50; i4x0->regs[0x03] = 0x12; /*82439HX*/ - i4x0->regs[0x08] = 0x00; /*A0 stepping*/ - i4x0->regs[0x51] = 0x20; - i4x0->regs[0x52] = 0xB5; /*512kb cache*/ - i4x0->regs[0x56] = 0x52; /*DRAM control*/ - i4x0->regs[0x59] = 0x40; - i4x0->regs[0x5A] = i4x0->regs[0x5B] = i4x0->regs[0x5C] = i4x0->regs[0x5D] = 0x44; - i4x0->regs[0x5E] = i4x0->regs[0x5F] = 0x44; - i4x0->regs[0x65] = i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02; - i4x0->regs[0x68] = 0x11; + regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */ + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + if (cpu_busspeed <= 50000000) + regs[0x57] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x57] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x57] |= 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x72] = 0x02; break; case INTEL_430VX: - i4x0->regs[0x02] = 0x30; i4x0->regs[0x03] = 0x70; /*82437VX*/ - i4x0->regs[0x08] = 0x00; /*A0 stepping*/ - i4x0->regs[0x52] = 0x42; /*256kb PLB cache*/ - i4x0->regs[0x53] = 0x14; - i4x0->regs[0x56] = 0x52; /*DRAM control*/ - i4x0->regs[0x67] = 0x11; - i4x0->regs[0x69] = 0x03; - i4x0->regs[0x70] = 0x20; - i4x0->regs[0x74] = 0x0e; - i4x0->regs[0x78] = 0x23; + regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */ + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + regs[0x53] = 0x14; + regs[0x56] = 0x52; + if (cpu_busspeed <= 50000000) + regs[0x57] |= 0x01; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + regs[0x57] |= 0x02; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x57] |= 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; + regs[0x67] = 0x11; + regs[0x69] = 0x03; + regs[0x70] = 0x20; + regs[0x72] = 0x02; + regs[0x74] = 0x0e; + regs[0x78] = 0x23; + break; + case INTEL_430TX: + regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */ + regs[0x08] = 0x01; + regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ + regs[0x53] = 0x14; + regs[0x56] = 0x52; + regs[0x57] = 0x01; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; + if (cpu_busspeed <= 60000000) + regs[0x67] |= 0x00; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x67] |= 0x80; + regs[0x70] = 0x20; + regs[0x72] = 0x02; break; #if defined(DEV_BRANCH) && defined(USE_I686) case INTEL_440FX: - i4x0->regs[0x02] = 0x37; i4x0->regs[0x03] = 0x12; /*82441FX*/ - i4x0->regs[0x08] = 0x02; /*A0 stepping*/ - i4x0->regs[0x2c] = 0xf4; - i4x0->regs[0x2d] = 0x1a; - i4x0->regs[0x2f] = 0x11; - i4x0->regs[0x51] = 0x01; - i4x0->regs[0x53] = 0x80; - i4x0->regs[0x58] = 0x10; - i4x0->regs[0x5a] = i4x0->regs[0x5b] = i4x0->regs[0x5c] = i4x0->regs[0x5d] = 0x11; - i4x0->regs[0x5e] = 0x11; - i4x0->regs[0x5f] = 0x31; + regs[0x02] = 0x37; regs[0x03] = 0x12; /* 82441FX */ + regs[0x08] = 0x02; + if (cpu_busspeed <= 60000000) + regs[0x51] |= 0x01; + else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667)) + regs[0x51] |= 0x02; + regs[0x53] = 0x80; + regs[0x57] = 0x01; + regs[0x58] = 0x10; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + regs[0x71] = 0x10; + regs[0x72] = 0x02; + break; + case INTEL_440BX: + regs[0x7a] = (info->local >> 8) & 0xff; + dev->max_func = (regs[0x7a] & 0x02) ? 0 : 1; + + regs[0x02] = (regs[0x7a] & 0x02) ? 0x90 : 0x92; regs[0x03] = 0x12; /* 82443BX */ + regs[0x08] = 0x02; + regs[0x10] = 0x08; + regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0; + if (cpu_busspeed <= 66666667) + regs[0x51] |= 0x00; + else if ((cpu_busspeed > 66666667) && (cpu_busspeed <= 100000000)) + regs[0x51] |= 0x20; + regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */ + regs[0x58] = 0x03; + regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01; + regs[0x72] = 0x02; + regs[0x73] = 0x38; + regs[0x7b] = 0x38; + regs[0x90] = 0x80; + regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02; + regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10; + regs[0xa4] = 0x03; + regs[0xa5] = 0x02; + regs[0xa7] = 0x1f; break; #endif } - i4x0->regs[0x04] = 0x06; i4x0->regs[0x05] = 0x00; -#if defined(DEV_BRANCH) && defined(USE_I686) - if (i4x0->type == INTEL_440FX) - i4x0->regs[0x06] = 0x80; -#endif - if (i4x0->type == INTEL_430FX) - i4x0->regs[0x07] = 0x82; -#if defined(DEV_BRANCH) && defined(USE_I686) - else if (i4x0->type != INTEL_440FX) -#else - else -#endif - i4x0->regs[0x07] = 0x02; - i4x0->regs[0x0b] = 0x06; - if (i4x0->type >= INTEL_430FX) - i4x0->regs[0x57] = 0x01; - else - i4x0->regs[0x57] = 0x31; - i4x0->regs[0x60] = i4x0->regs[0x61] = i4x0->regs[0x62] = i4x0->regs[0x63] = 0x02; - i4x0->regs[0x64] = 0x02; - if (i4x0->type >= INTEL_430FX) - i4x0->regs[0x72] = 0x02; + + regs[0x04] = 0x06; regs[0x07] = 0x02; + regs[0x0b] = 0x06; #if defined(DEV_BRANCH) && defined(USE_I686) - if (i4x0->type == INTEL_440FX) { + if (dev->type >= INTEL_440FX) { cpu_cache_ext_enabled = 1; cpu_update_waitstates(); } #endif - pci_add_card(0, i4x0_read, i4x0_write, i4x0); + i4x0_write(regs[0x59], 0x59, 0x00, dev); + i4x0_write(regs[0x5a], 0x5a, 0x00, dev); + i4x0_write(regs[0x5b], 0x5b, 0x00, dev); + i4x0_write(regs[0x5c], 0x5c, 0x00, dev); + i4x0_write(regs[0x5d], 0x5d, 0x00, dev); + i4x0_write(regs[0x5e], 0x5e, 0x00, dev); + i4x0_write(regs[0x5f], 0x5f, 0x00, dev); - return i4x0; + smbase = 0xa0000; + +#if defined(DEV_BRANCH) && defined(USE_I686) + if ((dev->type == INTEL_440BX) && (dev->max_func == 1)) { + regs = (uint8_t *) dev->regs[1]; + + regs[0x00] = 0x86; regs[0x01] = 0x80; /* Intel */ + regs[0x02] = 0x91; regs[0x03] = 0x71; /* 82443BX */ + regs[0x06] = 0x20; regs[0x07] = 0x02; + regs[0x08] = 0x02; + regs[0x0a] = 0x04; regs[0x0b] = 0x06; + regs[0x0e] = 0x01; + regs[0x1c] = 0xf0; + regs[0x1e] = 0xa0; regs[0x1f] = 0x02; + regs[0x20] = 0xf0; regs[0x21] = 0xff; + regs[0x24] = 0xf0; regs[0x25] = 0xff; + regs[0x3e] = 0x80; + } +#endif + + pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev); + + return dev; } @@ -345,6 +1272,21 @@ const device_t i420tx_device = }; +const device_t i420zx_device = +{ + "Intel 82424ZX", + DEVICE_PCI, + INTEL_420ZX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + const device_t i430lx_device = { "Intel 82434LX", @@ -435,6 +1377,21 @@ const device_t i430vx_device = }; +const device_t i430tx_device = +{ + "Intel 82439TX", + DEVICE_PCI, + INTEL_430TX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + #if defined(DEV_BRANCH) && defined(USE_I686) const device_t i440fx_device = { @@ -449,4 +1406,19 @@ const device_t i440fx_device = NULL, NULL }; + + +const device_t i440bx_device = +{ + "Intel 82443BX", + DEVICE_PCI, + 0x8000 | INTEL_440BX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; #endif diff --git a/src/chipset/intel_4x0.c.old b/src/chipset/intel_4x0.c.old new file mode 100644 index 000000000..3addcff70 --- /dev/null +++ b/src/chipset/intel_4x0.c.old @@ -0,0 +1,529 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel PCISet chips from 420TX to 440FX. + * + * Version: @(#)intel_4x0.c 1.0.3 2020/01/24 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2019,2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" +#include "chipset.h" + + +enum +{ + INTEL_420TX, + INTEL_430LX, + INTEL_430NX, + INTEL_430FX, + INTEL_430FX_PB640, + INTEL_430HX, + INTEL_430VX, + INTEL_430TX +#if defined(DEV_BRANCH) && defined(USE_I686) + ,INTEL_440FX +#endif +}; + +typedef struct +{ + uint8_t pm2_cntrl; + uint8_t regs[256]; + int type; +} i4x0_t; +static void +i4x0_map(uint32_t addr, uint32_t size, int state) +{ + // pclog("i4x0_map(%08X, %08X, %02X)\n", addr, size, state); + + switch (state & 3) { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + + +static void +i4x0_write(int func, int addr, uint8_t val, void *priv) +{ + i4x0_t *dev = (i4x0_t *) priv; + + if (func) + return; + + pclog("write %02X to %08X\n", val, addr); + + if ((addr >= 0x10) && (addr < 0x4f)) + return; + + switch (addr) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0e: + return; + + case 0x04: /*Command register*/ + if (dev->type >= INTEL_430FX) { + if (dev->type == INTEL_430FX_PB640) + val &= 0x06; + else + val &= 0x02; + } else + val &= 0x42; + val |= 0x04; + break; + case 0x05: + if (dev->type >= INTEL_430FX) + val = 0; + else + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + if (dev->type >= INTEL_430HX) { + val &= 0x80; + val |= 0x02; + } else { + val = 0x02; + if (dev->type == INTEL_430FX_PB640) + val |= 0x20; + } + break; + + case 0x52: /*Cache Control Register*/ +#if defined(DEV_BRANCH) && defined(USE_I686) + if (dev->type < INTEL_440FX) { +#endif + cpu_cache_ext_enabled = (val & 0x01); + cpu_update_waitstates(); +#if defined(DEV_BRANCH) && defined(USE_I686) + } +#endif + break; + + case 0x59: /*PAM0*/ + if ((dev->regs[0x59] ^ val) & 0xf0) { + i4x0_map(0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + break; + case 0x5a: /*PAM1*/ + if ((dev->regs[0x5a] ^ val) & 0x0f) + i4x0_map(0xc0000, 0x04000, val & 0xf); + if ((dev->regs[0x5a] ^ val) & 0xf0) + i4x0_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((dev->regs[0x5b] ^ val) & 0x0f) + i4x0_map(0xc8000, 0x04000, val & 0xf); + if ((dev->regs[0x5b] ^ val) & 0xf0) + i4x0_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((dev->regs[0x5c] ^ val) & 0x0f) + i4x0_map(0xd0000, 0x04000, val & 0xf); + if ((dev->regs[0x5c] ^ val) & 0xf0) + i4x0_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((dev->regs[0x5d] ^ val) & 0x0f) + i4x0_map(0xd8000, 0x04000, val & 0xf); + if ((dev->regs[0x5d] ^ val) & 0xf0) + i4x0_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((dev->regs[0x5e] ^ val) & 0x0f) + i4x0_map(0xe0000, 0x04000, val & 0xf); + if ((dev->regs[0x5e] ^ val) & 0xf0) + i4x0_map(0xe4000, 0x04000, val >> 4); + break; + case 0x5f: /*PAM6*/ + if ((dev->regs[0x5f] ^ val) & 0x0f) + i4x0_map(0xe8000, 0x04000, val & 0xf); + if ((dev->regs[0x5f] ^ val) & 0xf0) + i4x0_map(0xec000, 0x04000, val >> 4); + break; + case 0x72: /*SMRAM*/ + if ((dev->type >= INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x48)) + i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0); + else if ((dev->type < INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x20)) + i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0); + break; + + case 0x73: case 0x74: + // pclog("Access %i at %08X\n", dev->regs[0x73] & 3, dev->regs[0x74] << 19); + break; + } + + dev->regs[addr] = val; +} + + +static uint8_t +i4x0_read(int func, int addr, void *priv) +{ + i4x0_t *dev = (i4x0_t *) priv; + uint8_t ret = 0xff; + + if (!func) { + ret = dev->regs[addr]; + pclog("read %02X from %08X\n", ret, addr); + + // if (addr == 0x50) + // pclog("read %02X from %08X\n", ret, addr); + } + + return ret; +} + + +static void +i4x0_reset(void *priv) +{ + i4x0_t *i4x0 = (i4x0_t *)priv; + + i4x0_write(0, 0x59, 0x00, priv); + i4x0_write(0, 0x5e, 0x00, priv); + i4x0_write(0, 0x5f, 0x00, priv); + if (i4x0->type >= INTEL_430FX) + i4x0_write(0, 0x72, 0x02, priv); + + smbase = 0xa0000; +} + + +static void +i4x0_close(void *p) +{ + i4x0_t *i4x0 = (i4x0_t *)p; + + free(i4x0); +} + + +static uint8_t +pm2_cntrl_read(uint16_t addr, void *p) +{ + i4x0_t *dev = (i4x0_t *) p; + + return dev->pm2_cntrl & 0x01; +} + + +static void +pm2_cntrl_write(uint16_t addr, uint8_t val, void *p) +{ + i4x0_t *dev = (i4x0_t *) p; + + dev->pm2_cntrl = val & 0x01; +} + + +static void +*i4x0_init(const device_t *info) +{ + i4x0_t *i4x0 = (i4x0_t *) malloc(sizeof(i4x0_t)); + memset(i4x0, 0, sizeof(i4x0_t)); + + i4x0->type = info->local; + + i4x0->regs[0x00] = 0x86; i4x0->regs[0x01] = 0x80; /*Intel*/ + switch(i4x0->type) { + case INTEL_420TX: + i4x0->regs[0x02] = 0x83; i4x0->regs[0x03] = 0x04; /*82424TX/ZX*/ + i4x0->regs[0x08] = 0x03; /*A3 stepping*/ + i4x0->regs[0x50] = 0x80; + // i4x0->regs[0x50] = 0x23; + i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + break; + case INTEL_430LX: + i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/ + i4x0->regs[0x08] = 0x03; /*A3 stepping*/ + i4x0->regs[0x50] = 0x80; + i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + break; + case INTEL_430NX: + i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/ + i4x0->regs[0x08] = 0x10; /*A0 stepping*/ + i4x0->regs[0x50] = 0xA0; + i4x0->regs[0x52] = 0x44; /*256kb PLB cache*/ + i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02; + break; + case INTEL_430FX: + case INTEL_430FX_PB640: + i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/ + if (i4x0->type == INTEL_430FX_PB640) + i4x0->regs[0x08] = 0x02; /*???? stepping*/ + else + i4x0->regs[0x08] = 0x00; /*A0 stepping*/ + i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/ + break; + case INTEL_430HX: + i4x0->regs[0x02] = 0x50; i4x0->regs[0x03] = 0x12; /*82439HX*/ + i4x0->regs[0x08] = 0x00; /*A0 stepping*/ + i4x0->regs[0x51] = 0x20; + i4x0->regs[0x52] = 0xB5; /*512kb cache*/ + i4x0->regs[0x56] = 0x52; /*DRAM control*/ + // i4x0->regs[0x59] = 0x40; + // i4x0->regs[0x5A] = i4x0->regs[0x5B] = i4x0->regs[0x5C] = i4x0->regs[0x5D] = 0x44; + // i4x0->regs[0x5E] = i4x0->regs[0x5F] = 0x44; + i4x0->regs[0x65] = i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02; + i4x0->regs[0x68] = 0x11; + break; + case INTEL_430VX: + i4x0->regs[0x02] = 0x30; i4x0->regs[0x03] = 0x70; /*82437VX*/ + // i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/ + i4x0->regs[0x08] = 0x00; /*A0 stepping*/ + i4x0->regs[0x52] = 0x42; /*256kb PLB cache*/ + i4x0->regs[0x53] = 0x14; + i4x0->regs[0x56] = 0x52; /*DRAM control*/ + i4x0->regs[0x67] = 0x11; + i4x0->regs[0x69] = 0x03; + i4x0->regs[0x70] = 0x20; + i4x0->regs[0x74] = 0x0e; + i4x0->regs[0x78] = 0x23; + break; + case INTEL_430TX: + io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, i4x0); + i4x0->regs[0x02] = 0x00; i4x0->regs[0x03] = 0x71; /*82439TX*/ + i4x0->regs[0x08] = 0x01; /*A0 stepping*/ + i4x0->regs[0x52] = 0x42; /*256kb PLB cache*/ + i4x0->regs[0x53] = 0x14; + i4x0->regs[0x56] = 0x52; /*DRAM control*/ + i4x0->regs[0x65] = 0x02; + i4x0->regs[0x67] = 0x80; + i4x0->regs[0x69] = 0x03; + i4x0->regs[0x70] = 0x20; + break; +#if defined(DEV_BRANCH) && defined(USE_I686) + case INTEL_440FX: + i4x0->regs[0x02] = 0x37; i4x0->regs[0x03] = 0x12; /*82441FX*/ + i4x0->regs[0x08] = 0x02; /*A0 stepping*/ + i4x0->regs[0x2c] = 0xf4; + i4x0->regs[0x2d] = 0x1a; + i4x0->regs[0x2f] = 0x11; + i4x0->regs[0x51] = 0x01; + i4x0->regs[0x53] = 0x80; + i4x0->regs[0x58] = 0x10; + i4x0->regs[0x5a] = i4x0->regs[0x5b] = i4x0->regs[0x5c] = i4x0->regs[0x5d] = 0x11; + i4x0->regs[0x5e] = 0x11; + i4x0->regs[0x5f] = 0x31; + break; +#endif + } + i4x0->regs[0x04] = 0x06; i4x0->regs[0x05] = 0x00; +#if defined(DEV_BRANCH) && defined(USE_I686) + if (i4x0->type == INTEL_440FX) + i4x0->regs[0x06] = 0x80; +#endif + if (i4x0->type == INTEL_430FX) + i4x0->regs[0x07] = 0x82; +#if defined(DEV_BRANCH) && defined(USE_I686) + else if (i4x0->type != INTEL_440FX) +#else + else +#endif + i4x0->regs[0x07] = 0x02; + i4x0->regs[0x0b] = 0x06; + if (i4x0->type >= INTEL_430FX) + i4x0->regs[0x57] = 0x01; + else + i4x0->regs[0x57] = 0x31; + i4x0->regs[0x60] = i4x0->regs[0x61] = i4x0->regs[0x62] = i4x0->regs[0x63] = 0x02; + i4x0->regs[0x64] = 0x02; + if (i4x0->type >= INTEL_430FX) + i4x0->regs[0x72] = 0x02; + +#if defined(DEV_BRANCH) && defined(USE_I686) + if (i4x0->type == INTEL_440FX) { + cpu_cache_ext_enabled = 1; + cpu_update_waitstates(); + } +#endif + + pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, i4x0); + + i4x0_write(0, 0x59, 0x00, i4x0); + i4x0_write(0, 0x5a, 0x00, i4x0); + i4x0_write(0, 0x5b, 0x00, i4x0); + i4x0_write(0, 0x5c, 0x00, i4x0); + i4x0_write(0, 0x5d, 0x00, i4x0); + i4x0_write(0, 0x5e, 0x00, i4x0); + i4x0_write(0, 0x5f, 0x00, i4x0); + + smbase = 0xa0000; + + return i4x0; +} + + +const device_t i420tx_device = +{ + "Intel 82424TX", + DEVICE_PCI, + INTEL_420TX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430lx_device = +{ + "Intel 82434LX", + DEVICE_PCI, + INTEL_430LX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430nx_device = +{ + "Intel 82434NX", + DEVICE_PCI, + INTEL_430NX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430fx_device = +{ + "Intel SB82437FX-66", + DEVICE_PCI, + INTEL_430FX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430fx_pb640_device = +{ + "Intel SB82437FX-66 (PB640)", + DEVICE_PCI, + INTEL_430FX_PB640, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430hx_device = +{ + "Intel 82439HX", + DEVICE_PCI, + INTEL_430HX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430vx_device = +{ + "Intel 82437VX", + DEVICE_PCI, + INTEL_430VX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +const device_t i430tx_device = +{ + "Intel 82439TX", + DEVICE_PCI, + INTEL_430TX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; + + +#if defined(DEV_BRANCH) && defined(USE_I686) +const device_t i440fx_device = +{ + "Intel 82441FX", + DEVICE_PCI, + INTEL_440FX, + i4x0_init, + i4x0_close, + i4x0_reset, + NULL, + NULL, + NULL, + NULL +}; +#endif diff --git a/src/chipset/neat.c b/src/chipset/neat.c index cc641c0d5..dc2798813 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -24,15 +24,15 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "keyboard.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" #include "chipset.h" #define NEAT_DEBUG 0 diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index b6ffb0ff8..21fa9f048 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -258,15 +258,15 @@ SeeAlso: #P0178,#P0187 #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "device.h" +#include "keyboard.h" +#include "mem.h" +#include "fdd.h" +#include "fdc.h" #include "chipset.h" diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 093b3863a..c6f3619c3 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -13,7 +13,7 @@ * 8MB of DRAM chips', because it works fine with bus-based * memory expansion. * - * Version: @(#)scamp.c 1.0.0 2020/01/21 + * Version: @(#)scamp.c 1.0.1 2020/01/22 * * Authors: Sarah Walker, * @@ -24,16 +24,21 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../port_92.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "port_92.h" #include "chipset.h" +typedef struct { + void *parent; + int bank; +} ram_struct_t; + typedef struct { int cfg_index; uint8_t cfg_regs[256]; @@ -42,6 +47,9 @@ typedef struct { int ram_config; mem_mapping_t ram_mapping[2]; + + ram_struct_t ram_struct[3]; + uint32_t ram_virt_base[2], ram_phys_base[2]; uint32_t ram_mask[2]; int row_virt_shift[2], row_phys_shift[2]; @@ -129,8 +137,9 @@ static const struct static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -156,8 +165,9 @@ ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -186,8 +196,9 @@ ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -213,8 +224,9 @@ ram_mirrored_interleaved_read(uint32_t addr, void *priv) static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -242,8 +254,9 @@ ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) static uint8_t ram_mirrored_read(uint32_t addr, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -257,8 +270,9 @@ ram_mirrored_read(uint32_t addr, void *priv) static void ram_mirrored_write(uint32_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - int bank = (int)priv; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank; int row, column, byte; addr -= dev->ram_virt_base[bank]; @@ -674,14 +688,19 @@ scamp_init(const device_t *info) mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); + dev->ram_struct[2].parent = dev; + dev->ram_struct[2].bank = 0; + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[2]); mem_mapping_disable(&ram_high_mapping); addr = 0; for (c = 0; c < 2; c++) { + dev->ram_struct[c].parent = dev; + dev->ram_struct[c].bank = c; mem_mapping_add(&dev->ram_mapping[c], 0, 0, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL, - &ram[addr], MEM_MAPPING_INTERNAL, (void *)c); + &ram[addr], MEM_MAPPING_INTERNAL, (void *) &dev->ram_struct[c]); mem_mapping_disable(&dev->ram_mapping[c]); dev->ram_phys_base[c] = addr; diff --git a/src/chipset/scat.c b/src/chipset/scat.c index d5712a98c..a9b668141 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -23,24 +23,19 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/cpu.h" -#include "../cpu_new/x86.h" -#else -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#endif -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../port_92.h" -#include "../rom.h" +#include "86box.h" +#include "device.h" +#include "cpu.h" +#include "x86.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "keyboard.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "port_92.h" +#include "rom.h" #include "chipset.h" diff --git a/src/chipset/sis_85c471.c b/src/chipset/sis_85c471.c index 934e84c55..d28d824c1 100644 --- a/src/chipset/sis_85c471.c +++ b/src/chipset/sis_85c471.c @@ -22,20 +22,20 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../io.h" -#include "../lpt.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../timer.h" -#include "../port_92.h" -#include "../serial.h" -#include "../machine/machine.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "lpt.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "hdc_ide.h" +#include "keyboard.h" +#include "timer.h" +#include "port_92.h" +#include "serial.h" +#include "machine.h" #include "chipset.h" diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index cddb74b9d..51888f23f 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -21,18 +21,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../timer.h" -#include "../port_92.h" -#include "../disk/hdc_ide.h" -#include "../machine/machine.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" +#include "timer.h" +#include "port_92.h" +#include "hdc_ide.h" +#include "machine.h" #include "chipset.h" @@ -120,6 +120,8 @@ sis_85c496_write(int func, int addr, uint8_t val, void *priv) if ((addr >= 4 && addr < 8) || addr >= 0x40) dev->pci_conf[addr] = val; + pclog("SiS 496 Write: %02X %02X %02X\n", func, addr, val); + valxor = old ^ val; switch (addr) { @@ -239,15 +241,20 @@ static uint8_t sis_85c496_read(int func, int addr, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; + uint8_t ret = dev->pci_conf[addr]; switch (addr) { case 0x82: /*Port 22h Mirror*/ - return inb(0x22); + ret = inb(0x22); + break; case 0x70: /*Port 70h Mirror*/ - return inb(0x70); + ret = inb(0x70); + break; } - return dev->pci_conf[addr]; + pclog("SiS 496 Read: %02X %02X %02X\n", func, addr, ret); + + return ret; } @@ -313,7 +320,7 @@ static void dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */ dev->pci_conf[0xd1] = 0xff; - pci_add_card(5, sis_85c496_read, sis_85c496_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c496_read, sis_85c496_write, dev); sis_85c497_reset(dev); diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index f5a67198d..605799e17 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -20,14 +20,14 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" -#include "../port_92.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" +#include "port_92.h" #include "chipset.h" diff --git a/src/chipset/via_mvp3.c b/src/chipset/via_mvp3.c index d9ffc01a6..cdbcc17d1 100644 --- a/src/chipset/via_mvp3.c +++ b/src/chipset/via_mvp3.c @@ -21,13 +21,13 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../keyboard.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "keyboard.h" #include "chipset.h" @@ -292,7 +292,7 @@ via_mvp3_init(const device_t *info) { via_mvp3_t *dev = (via_mvp3_t *) malloc(sizeof(via_mvp3_t)); - pci_add_card(0, via_mvp3_read, via_mvp3_write, dev); + pci_add_card(PCI_ADD_NORTHBRIDGE, via_mvp3_read, via_mvp3_write, dev); via_mvp3_setup(dev); diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index e469f6672..f01290e65 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -23,17 +23,17 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../io.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../port_92.h" -#include "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../video/vid_paradise.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "86box_io.h" +#include "keyboard.h" +#include "mem.h" +#include "port_92.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "video.h" #include "chipset.h" diff --git a/src/cksum.d b/src/cksum.d new file mode 100644 index 000000000..aeba67afb --- /dev/null +++ b/src/cksum.d @@ -0,0 +1,9 @@ +cksum.o: network/slirp/cksum.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/codegen.d b/src/codegen.d new file mode 100644 index 000000000..fca8209c8 --- /dev/null +++ b/src/codegen.d @@ -0,0 +1,3 @@ +codegen.o: cpu/codegen.c 86box.h mem.h cpu_common/cpu.h \ + cpu_common/x86_ops.h cpu/codegen.h cpu/../mem.h \ + cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h diff --git a/src/codegen_ops.d b/src/codegen_ops.d new file mode 100644 index 000000000..cb8054d5b --- /dev/null +++ b/src/codegen_ops.d @@ -0,0 +1,8 @@ +codegen_ops.o: cpu/codegen_ops.c 86box.h mem.h cpu_common/cpu.h \ + cpu_common/x86.h cpu_common/x86_ops.h cpu/x86_flags.h cpu_common/x87.h \ + cpu_common/386_common.h cpu/codegen.h cpu/../mem.h \ + cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h cpu/codegen_ops.h \ + cpu/codegen_ops_x86.h cpu/codegen_ops_arith.h cpu/codegen_ops_fpu.h \ + cpu/codegen_ops_jump.h cpu/codegen_ops_logic.h cpu/codegen_ops_misc.h \ + cpu/codegen_ops_mmx.h cpu/codegen_ops_mov.h cpu/codegen_ops_shift.h \ + cpu/codegen_ops_stack.h cpu/codegen_ops_xchg.h diff --git a/src/codegen_timing_486.d b/src/codegen_timing_486.d new file mode 100644 index 000000000..8d3af27ac --- /dev/null +++ b/src/codegen_timing_486.d @@ -0,0 +1,4 @@ +codegen_timing_486.o: cpu/codegen_timing_486.c 86box.h mem.h \ + cpu_common/cpu.h cpu_common/x86.h cpu_common/x86_ops.h cpu_common/x87.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h \ + cpu/codegen_ops.h cpu/codegen_timing_common.h diff --git a/src/codegen_timing_686.d b/src/codegen_timing_686.d new file mode 100644 index 000000000..a660a82f5 --- /dev/null +++ b/src/codegen_timing_686.d @@ -0,0 +1,4 @@ +codegen_timing_686.o: cpu/codegen_timing_686.c 86box.h mem.h \ + cpu_common/cpu.h cpu_common/x86.h cpu_common/x86_ops.h cpu_common/x87.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h \ + cpu/codegen_timing_common.h cpu/codegen_ops.h diff --git a/src/codegen_timing_common.d b/src/codegen_timing_common.d new file mode 100644 index 000000000..455d6847e --- /dev/null +++ b/src/codegen_timing_common.d @@ -0,0 +1,3 @@ +codegen_timing_common.o: cpu/codegen_timing_common.c 86box.h \ + cpu_common/cpu.h cpu/codegen_timing_common.h cpu/codegen_ops.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h diff --git a/src/codegen_timing_pentium.d b/src/codegen_timing_pentium.d new file mode 100644 index 000000000..a7f60a21d --- /dev/null +++ b/src/codegen_timing_pentium.d @@ -0,0 +1,4 @@ +codegen_timing_pentium.o: cpu/codegen_timing_pentium.c 86box.h mem.h \ + cpu_common/cpu.h cpu_common/x86.h cpu_common/x86_ops.h cpu_common/x87.h \ + cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h \ + cpu/codegen_ops.h cpu/codegen_timing_common.h diff --git a/src/codegen_timing_winchip.d b/src/codegen_timing_winchip.d new file mode 100644 index 000000000..cbea6e70a --- /dev/null +++ b/src/codegen_timing_winchip.d @@ -0,0 +1,4 @@ +codegen_timing_winchip.o: cpu/codegen_timing_winchip.c 86box.h \ + cpu_common/cpu.h cpu_common/x86.h cpu_common/x86_ops.h cpu_common/x87.h \ + cpu/../mem.h cpu/codegen.h cpu/../cpu_common/x86_ops.h cpu/codegen_x86.h \ + cpu/codegen_ops.h cpu/codegen_timing_common.h diff --git a/src/codegen_x86.d b/src/codegen_x86.d new file mode 100644 index 000000000..edd9a9214 --- /dev/null +++ b/src/codegen_x86.d @@ -0,0 +1,4 @@ +codegen_x86.o: cpu/codegen_x86.c 86box.h cpu_common/cpu.h mem.h \ + cpu_common/x86.h cpu/x86_flags.h cpu/../cpu_common/x86_ops.h \ + cpu_common/x87.h cpu_common/386_common.h cpu/codegen.h cpu/../mem.h \ + cpu/codegen_x86.h cpu/codegen_ops.h cpu/codegen_ops_x86.h diff --git a/src/config.c b/src/config.c index f2b6076c1..707bf0534 100644 --- a/src/config.c +++ b/src/config.c @@ -34,7 +34,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "device.h" #include "timer.h" #include "nvr.h" @@ -42,24 +42,23 @@ #include "isamem.h" #include "isartc.h" #include "lpt.h" -#include "disk/hdd.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "game/gameport.h" -#include "machine/machine.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "machine.h" #include "mouse.h" -#include "network/network.h" -#include "scsi/scsi.h" -#include "scsi/scsi_device.h" -#include "cdrom/cdrom.h" -#include "disk/zip.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_mpu401.h" -#include "sound/sound.h" -#include "video/video.h" +#include "network.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "sound.h" +#include "midi.h" +#include "snd_mpu401.h" +#include "video.h" #include "plat.h" #include "plat_midi.h" #include "ui.h" @@ -309,7 +308,7 @@ config_read(wchar_t *fn) /* Create a new section and insert it. */ ns = malloc(sizeof(section_t)); memset(ns, 0x00, sizeof(section_t)); - strncpy(ns->name, sname, sizeof(ns->name) - 1); + memcpy(ns->name, sname, 128); list_add(&ns->list, &config_head); /* New section is now the current one. */ @@ -339,7 +338,7 @@ config_read(wchar_t *fn) /* Allocate a new variable entry.. */ ne = malloc(sizeof(entry_t)); memset(ne, 0x00, sizeof(entry_t)); - strncpy(ne->name, ename, sizeof(ne->name) - 1); + memcpy(ne->name, ename, 128); wcsncpy(ne->wdata, &buff[d], sizeof_w(ne->wdata)-1); ne->wdata[sizeof_w(ne->wdata)-1] = L'\0'; wcstombs(ne->data, ne->wdata, sizeof(ne->data)); diff --git a/src/config.d b/src/config.d new file mode 100644 index 000000000..e3d047890 --- /dev/null +++ b/src/config.d @@ -0,0 +1,6 @@ +config.o: config.c 86box.h cpu_common/cpu.h device.h timer.h nvr.h \ + config.h isamem.h isartc.h lpt.h disk/hdd.h disk/hdc.h disk/hdc_ide.h \ + floppy/fdd.h floppy/fdc.h game/gameport.h machine/machine.h mouse.h \ + network/network.h scsi/scsi.h scsi/scsi_device.h cdrom/cdrom.h \ + disk/zip.h sound/sound.h sound/midi.h sound/snd_mpu401.h video/video.h \ + plat.h lang/language.h plat_midi.h ui.h diff --git a/src/convolve-sse.d b/src/convolve-sse.d new file mode 100644 index 000000000..688d6dc87 --- /dev/null +++ b/src/convolve-sse.d @@ -0,0 +1,4 @@ +convolve-sse.o: sound/resid-fp/convolve-sse.cc sound/resid-fp/sid.h \ + sound/resid-fp/siddefs-fp.h sound/resid-fp/voice.h sound/resid-fp/wave.h \ + sound/resid-fp/envelope.h sound/resid-fp/filter.h \ + sound/resid-fp/extfilt.h sound/resid-fp/pot.h diff --git a/src/convolve.d b/src/convolve.d new file mode 100644 index 000000000..60863dc41 --- /dev/null +++ b/src/convolve.d @@ -0,0 +1 @@ +convolve.o: sound/resid-fp/convolve.cc diff --git a/src/cpu.d b/src/cpu.d new file mode 100644 index 000000000..1b4039165 --- /dev/null +++ b/src/cpu.d @@ -0,0 +1,4 @@ +cpu.o: cpu_common/cpu.c 86box.h cpu_common/cpu.h device.h \ + machine/machine.h 86box_io.h cpu_common/x86_ops.h mem.h nmi.h pic.h \ + pci.h cpu/codegen.h cpu/../mem.h cpu/../cpu_common/x86_ops.h \ + cpu/codegen_x86.h diff --git a/src/cpu.txt b/src/cpu.txt new file mode 100644 index 000000000..670721fd5 --- /dev/null +++ b/src/cpu.txt @@ -0,0 +1,3 @@ +Comparing files CPU\cpu.c and CPU_NEW\CPU.C +FC: no differences encountered + diff --git a/src/cpu/386.c b/src/cpu/386.c deleted file mode 100644 index e4d011bc9..000000000 --- a/src/cpu/386.c +++ /dev/null @@ -1,256 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#ifndef INFINITY -# define INFINITY (__builtin_inff()) -#endif -#define HAVE_STDARG_H -#include "../86box.h" -#include "cpu.h" -#include "../timer.h" -#include "x86.h" -#include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "386_common.h" - - -#define CPU_BLOCK_END() - -extern int codegen_flags_changed; - -int cpl_override = 0, fpucount = 0; -int tempc, oldcpl, optype, inttype, oddeven = 0; -int stack32, timetolive; - -uint16_t oldcs; - -uint32_t use32; -uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; -uint32_t *eal_r, *eal_w; -uint32_t oxpc, cr2, cr3, cr4; -uint32_t dr[8]; -uint32_t rmdat32; -uint32_t backupregs[16]; - -x86seg gdt,ldt,idt,tr; -x86seg _oldds; - -uint32_t rmdat; - -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 - - -#include "x86_flags.h" - -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 -extern int xout; - -int oldi; - -uint32_t testr[9]; -extern int dontprint; - -#undef NOTRM -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 0; \ - } - -#define OP_TABLE(name) ops_ ## name - -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - -#include "x86_ops.h" - -#undef NOTRM -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - break; \ - } - - -#ifdef ENABLE_386_LOG -int x386_do_log = ENABLE_386_LOG; - - -static void -x386_log(const char *fmt, ...) -{ - va_list ap; - - if (x386_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define x386_log(fmt, ...) -#endif - - -void exec386(int cycs) -{ - int vector, tempi, cycdiff, oldcyc; - int ins_cycles; - uint32_t addr; - - cycles+=cycs; - while (cycles>0) - { - int cycle_period = (timer_target - (uint32_t)tsc) + 1; - - x86_was_reset = 0; - cycdiff=0; - oldcyc=cycles; - while (cycdiff < cycle_period) - { - ins_cycles = cycles; - - oldcs=CS; - cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; - cpu_state.op32 = use32; - - x86_was_reset = 0; - -dontprint=0; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if(x86_was_reset) - break; - } - - if (!use32) cpu_state.pc &= 0xffff; - - if (cpu_state.abrt) - { - flags_rebuild(); - tempi = cpu_state.abrt; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - CS = oldcs; - cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - x386_log("Triple fault - reset\n"); - } - } - } - - ins_cycles -= cycles; - tsc += ins_cycles; - - cycdiff=oldcyc-cycles; - - if (trap) - { - flags_rebuild(); - /* oldpc=pc; */ - /* oldcs=CS; */ - if (msw&1) - { - pmodeint(1,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - else if (nmi && nmi_enable) - { - cpu_state.oldpc = cpu_state.pc; - oldcs = CS; - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) - { - nmi_auto_clear = 0; - nmi = 0; - } - } - else if ((cpu_state.flags & I_FLAG) && pic_intpending) - { - vector = picinterrupt(); - if (vector != -1) - { - flags_rebuild(); - if (msw&1) - { - pmodeint(vector,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (vector << 2) + idt.base; - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc = cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - } - - ins++; - - if (timetolive) - { - timetolive--; - if (!timetolive) - fatal("Life expired\n"); - } - - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); - } - } -} diff --git a/src/cpu/codegen.c b/src/cpu/codegen.c index d951f650c..44b1c502d 100644 --- a/src/cpu/codegen.c +++ b/src/cpu/codegen.c @@ -2,8 +2,9 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" + +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86_ops.h" #include "codegen.h" diff --git a/src/cpu/codegen.h b/src/cpu/codegen.h index 38847f78b..f7c41f849 100644 --- a/src/cpu/codegen.h +++ b/src/cpu/codegen.h @@ -38,7 +38,7 @@ #define _CODEGEN_H_ #include "../mem.h" -#include "x86_ops.h" +#include "../cpu_common/x86_ops.h" #ifdef __amd64__ #include "codegen_x86-64.h" @@ -315,9 +315,6 @@ extern int cpu_recomp_evicted, cpu_recomp_evicted_latched; extern int cpu_recomp_reuse, cpu_recomp_reuse_latched; extern int cpu_recomp_removed, cpu_recomp_removed_latched; -extern int cpu_reps, cpu_reps_latched; -extern int cpu_notreps, cpu_notreps_latched; - extern int codegen_block_cycles; extern void (*codegen_timing_start)(); diff --git a/src/cpu/codegen_ops.c b/src/cpu/codegen_ops.c index a577d3b6e..229fa1882 100644 --- a/src/cpu/codegen_ops.c +++ b/src/cpu/codegen_ops.c @@ -2,8 +2,9 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" + +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_ops_x86-64.h b/src/cpu/codegen_ops_x86-64.h index de6763561..9508a83bd 100644 --- a/src/cpu/codegen_ops_x86-64.h +++ b/src/cpu/codegen_ops_x86-64.h @@ -4663,11 +4663,6 @@ static inline void FP_OP_IL(int op) FP_OP_MEM(op); } -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - static inline void FP_COMPARE_REG(int dst, int src) { addbyte(0x8b); /*MOV EAX, [TOP]*/ diff --git a/src/cpu/codegen_ops_x86.h b/src/cpu/codegen_ops_x86.h index 225490cd3..13ca37c4c 100644 --- a/src/cpu/codegen_ops_x86.h +++ b/src/cpu/codegen_ops_x86.h @@ -2951,10 +2951,6 @@ static inline void FP_OP_IQ(int op) } } #endif -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) static inline void FP_COMPARE_S() { diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index 3f45d117e..912bfc16b 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -2,8 +2,8 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index fc818d7f1..dc901dddc 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -12,8 +12,8 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_timing_common.c b/src/cpu/codegen_timing_common.c index f53a8fc4d..c9ac19766 100644 --- a/src/cpu/codegen_timing_common.c +++ b/src/cpu/codegen_timing_common.c @@ -2,7 +2,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "codegen_timing_common.h" diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index 88c4e9544..3a625ed6d 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -13,8 +13,8 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" +#include "86box.h" +#include "mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index 93717c4a6..7074307ef 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -2,7 +2,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu/codegen_x86-64.c b/src/cpu/codegen_x86-64.c index 42136207c..c0ece0ce0 100644 --- a/src/cpu/codegen_x86-64.c +++ b/src/cpu/codegen_x86-64.c @@ -5,13 +5,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" -#include "../mem.h" +#include "mem.h" #include "386_common.h" diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index a3352943f..b6fd2a49b 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -43,12 +43,12 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" -#include "x86_ops.h" +#include "../cpu_common/x86_ops.h" #include "x87.h" #include "386_common.h" diff --git a/src/cpu/x86_ops_arith_ex.h b/src/cpu/x86_ops_arith_ex.h deleted file mode 100644 index cc4fcd7c3..000000000 --- a/src/cpu/x86_ops_arith_ex.h +++ /dev/null @@ -1,752 +0,0 @@ -#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ - static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _AL_imm(uint32_t fetchdat) \ - { \ - uint8_t dst = AL; \ - uint8_t src = getbytef(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 8 flagops; \ - AL = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _AX_imm(uint32_t fetchdat) \ - { \ - uint16_t dst = AX; \ - uint16_t src = getwordf(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 16 flagops; \ - AX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _EAX_imm(uint32_t fetchdat) \ - { \ - uint32_t dst = EAX; \ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 32 flagops; \ - EAX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } - -OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) -OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) -OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) -OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1) -OP_ARITH(OR, dst | src, setznp, (dst | src), 0) -OP_ARITH(AND, dst & src, setznp, (dst & src), 0) -OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) - -static int opCMP_b_rmw_a16(uint32_t fetchdat) -{ - uint8_t dst; - fetch_ea_16(fetchdat); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_b_rmw_a32(uint32_t fetchdat) -{ - uint8_t dst; - fetch_ea_32(fetchdat); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_w_rmw_a16(uint32_t fetchdat) -{ - uint16_t dst; - fetch_ea_16(fetchdat); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_w_rmw_a32(uint32_t fetchdat) -{ - uint16_t dst; - fetch_ea_32(fetchdat); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_l_rmw_a16(uint32_t fetchdat) -{ - uint32_t dst; - fetch_ea_16(fetchdat); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; -} -static int opCMP_l_rmw_a32(uint32_t fetchdat) -{ - uint32_t dst; - fetch_ea_32(fetchdat); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; -} - -static int opCMP_b_rm_a16(uint32_t fetchdat) -{ - uint8_t src; - fetch_ea_16(fetchdat); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_b_rm_a32(uint32_t fetchdat) -{ - uint8_t src; - fetch_ea_32(fetchdat); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_w_rm_a16(uint32_t fetchdat) -{ - uint16_t src; - fetch_ea_16(fetchdat); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opCMP_w_rm_a32(uint32_t fetchdat) -{ - uint16_t src; - fetch_ea_32(fetchdat); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opCMP_l_rm_a16(uint32_t fetchdat) -{ - uint32_t src; - fetch_ea_16(fetchdat); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; -} -static int opCMP_l_rm_a32(uint32_t fetchdat) -{ - uint32_t src; - fetch_ea_32(fetchdat); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; -} - -static int opCMP_AL_imm(uint32_t fetchdat) -{ - uint8_t src = getbytef(); - setsub8(AL, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} - -static int opCMP_AX_imm(uint32_t fetchdat) -{ - uint16_t src = getwordf(); - setsub16(AX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} - -static int opCMP_EAX_imm(uint32_t fetchdat) -{ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; - setsub32(EAX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} - -static int opTEST_b_a16(uint32_t fetchdat) -{ - uint8_t temp, temp2; - fetch_ea_16(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opTEST_b_a32(uint32_t fetchdat) -{ - uint8_t temp, temp2; - fetch_ea_32(fetchdat); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opTEST_w_a16(uint32_t fetchdat) -{ - uint16_t temp, temp2; - fetch_ea_16(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; -} -static int opTEST_w_a32(uint32_t fetchdat) -{ - uint16_t temp, temp2; - fetch_ea_32(fetchdat); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; -} - -static int opTEST_l_a16(uint32_t fetchdat) -{ - uint32_t temp, temp2; - fetch_ea_16(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; -} -static int opTEST_l_a32(uint32_t fetchdat) -{ - uint32_t temp, temp2; - fetch_ea_32(fetchdat); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; -} - -static int opTEST_AL(uint32_t fetchdat) -{ - uint8_t temp = getbytef(); - setznp8(AL & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opTEST_AX(uint32_t fetchdat) -{ - uint16_t temp = getwordf(); - setznp16(AX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; -} -static int opTEST_EAX(uint32_t fetchdat) -{ - uint32_t temp = getlong(); if (cpu_state.abrt) return 1; - setznp32(EAX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; -} - - -#define ARITH_MULTI(ea_width, flag_width, is32) \ - dst = read ## ea_width(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - switch ((rmdat >> 3) & 7) \ - { \ - case 0x00: /*ADD ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - write ## ea_width(easeg, cpu_state.eaaddr, dst + src); if (cpu_state.abrt) return 1; \ - setadd ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x01: /*OR ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - dst |= src; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x02: /*ADC ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - tempc = CF_SET() ? 1 : 0; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst + src + tempc); if (cpu_state.abrt) return 1; \ - setadc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x03: /*SBB ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - tempc = CF_SET() ? 1 : 0; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst - (src + tempc)); if (cpu_state.abrt) return 1; \ - setsbc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x04: /*AND ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - dst &= src; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x05: /*SUB ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - write ## ea_width(easeg, cpu_state.eaaddr, dst - src); if (cpu_state.abrt) return 1; \ - setsub ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x06: /*XOR ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \ - dst ^= src; \ - write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x07: /*CMP ea, #*/ \ - if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 0, is32) \ - setsub ## flag_width(dst, src); \ - if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ - else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ - break; \ - } - - -static int op80_a16(uint32_t fetchdat) -{ - uint8_t src, dst; - - fetch_ea_16(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(8, 8, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - - return 0; -} -static int op80_a32(uint32_t fetchdat) -{ - uint8_t src, dst; - - fetch_ea_32(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(8, 8, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - - return 0; -} -static int op81_w_a16(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_16(fetchdat); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(16, 16, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - - return 0; -} -static int op81_w_a32(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_32(fetchdat); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(16, 16, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - - return 0; -} -static int op81_l_a16(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_16(fetchdat); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(32, 32, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - - return 0; -} -static int op81_l_a32(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_32(fetchdat); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(32, 32, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - - return 0; -} - -static int op83_w_a16(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_16(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(16, 16, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - - return 0; -} -static int op83_w_a32(uint32_t fetchdat) -{ - uint16_t src, dst; - - fetch_ea_32(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(16, 16, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - - return 0; -} - -static int op83_l_a16(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_16(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(32, 32, 0); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - - return 0; -} -static int op83_l_a32(uint32_t fetchdat) -{ - uint32_t src, dst; - - fetch_ea_32(fetchdat); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(32, 32, 1); - if ((rmdat & 0x38) == 0x38) - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - else - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - - return 0; -} - diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 036dfcfe4..ced052ea0 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -24,13 +24,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../timer.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../nvr.h" +#include "device.h" +#include "timer.h" +#include "machine.h" +#include "mem.h" +#include "nvr.h" #include "x86.h" #include "x86_flags.h" #include "386_common.h" @@ -108,8 +108,8 @@ static void seg_reset(x86seg *s) if(s == &cpu_state.seg_cs) { // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. - //s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; - s->base = AT ? 0xF0000 : 0xFFFF0; + s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; + // s->base = AT ? 0xF0000 : 0xFFFF0; s->seg = AT ? 0xF000 : 0xFFFF; } else diff --git a/src/cpu/x87.h b/src/cpu/x87.h deleted file mode 100644 index 6d2cb3ca9..000000000 --- a/src/cpu/x87.h +++ /dev/null @@ -1,26 +0,0 @@ -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; - -static __inline void x87_set_mmx() -{ - uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 1; -} - -static __inline void x87_emms() -{ - uint64_t *p; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 0; -} - - -uint16_t x87_gettag(); -void x87_settag(uint16_t new_tag); - -/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ -#define TAG_UINT64 (1 << 2) diff --git a/src/cpu_common.bak/386.c b/src/cpu_common.bak/386.c new file mode 100644 index 000000000..416f9577e --- /dev/null +++ b/src/cpu_common.bak/386.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "x86.h" +#include "x87.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" +#include "386_common.h" +#ifdef USE_NEW_DYNAREC +#include "codegen.h" +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + + +extern int codegen_flags_changed; + +int tempc, oldcpl, optype, inttype, oddeven = 0; +int timetolive; + +uint16_t oldcs; + +uint32_t oldds, oldss, olddslimit, oldsslimit, + olddslimitw, oldsslimitw; +uint32_t oxpc; +uint32_t rmdat32; +uint32_t backupregs[16]; + +x86seg _oldds; + + +#ifdef ENABLE_386_LOG +int x386_do_log = ENABLE_386_LOG; + + +void +x386_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_log(fmt, ...) +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + +static inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; +// pc++; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +static inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 + +#include "x86_flags.h" + +#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ +#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 +#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ +#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + + +#define OP_TABLE(name) ops_ ## name + +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "x86_ops.h" + +void +exec386(int cycs) +{ + // uint8_t opcode; + int vector, tempi, cycdiff, oldcyc; + int cycle_period, ins_cycles; + uint32_t addr; + + cycles += cycs; + + while (cycles > 0) { + cycle_period = (timer_target - (uint32_t)tsc) + 1; + + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; + +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl=CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + +#ifndef USE_NEW_DYNAREC + x86_was_reset = 0; +#endif + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + cpu_state.pc = cpu_state.oldpc; + x386_log("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_LOG + x386_log("Triple fault - reset\n"); +#endif + } + } + } + + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff = oldcyc - cycles; + + if (trap) { + flags_rebuild(); + if (msw&1) + pmodeint(1,0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } + } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } + + ins++; + + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process(); + } + } +} diff --git a/src/cpu_new/386_common.c b/src/cpu_common.bak/386_common.c similarity index 93% rename from src/cpu_new/386_common.c rename to src/cpu_common.bak/386_common.c index 32b65e0bf..cb140c41a 100644 --- a/src/cpu_new/386_common.c +++ b/src/cpu_common.bak/386_common.c @@ -9,17 +9,17 @@ # define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../timer.h" +#include "timer.h" #include "x86.h" #include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" #include "386_common.h" #include "x86_flags.h" #include "codegen.h" @@ -45,7 +45,11 @@ int cpl_override=0; int fpucount=0; +#ifdef USE_NEW_DYNAREC uint16_t cpu_cur_status = 0; +#else +uint32_t cpu_cur_status = 0; +#endif uint32_t pccache; uint8_t *pccache2; @@ -117,6 +121,9 @@ void x86_int(int num) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } @@ -161,6 +168,9 @@ void x86_int_sw(int num) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); cycles -= timing_int_rm; @@ -197,6 +207,9 @@ int x86_int_sw_rm(int num) cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; loadcs(new_cs); +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cycles -= timing_int_rm; trap = 0; @@ -220,7 +233,11 @@ int checkio(int port) if (cpu_state.abrt) return 0; if ((t+(port>>3))>tr.limit) return 1; cpl_override = 1; +#ifdef USE_NEW_DYNAREC d = readmembl(tr.base + t + (port >> 3)); +#else + d = readmemb386l(0, tr.base + t + (port >> 3)); +#endif cpl_override = 0; return d&(1<<(port&7)); } diff --git a/src/cpu_new/386_common.h b/src/cpu_common.bak/386_common.h similarity index 100% rename from src/cpu_new/386_common.h rename to src/cpu_common.bak/386_common.h diff --git a/src/cpu/386_dynarec.c b/src/cpu_common.bak/386_dynarec - Cópia (2).c similarity index 85% rename from src/cpu/386_dynarec.c rename to src/cpu_common.bak/386_dynarec - Cópia (2).c index 67594c786..421381dd3 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu_common.bak/386_dynarec - Cópia (2).c @@ -8,31 +8,31 @@ #ifndef INFINITY # define INFINITY (__builtin_inff()) #endif + #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" #ifdef USE_DYNAREC #include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif #endif #include "386_common.h" #define CPU_BLOCK_END() cpu_block_end = 1 -uint32_t cpu_cur_status = 0; - -int cpu_reps, cpu_reps_latched; -int cpu_notreps, cpu_notreps_latched; int inrecomp = 0, cpu_block_end = 0; int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; @@ -55,7 +55,7 @@ x386_dynarec_log(const char *fmt, ...) } } #else -#define x86_dynarec_log (fmt, ...) +#define x386_dynarec_log(fmt, ...) #endif @@ -175,155 +175,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) #include "x86_flags.h" -void x86_int(int num) -{ - uint32_t addr; - flags_rebuild(); - cpu_state.pc=cpu_state.oldpc; - if (msw&1) - { - pmodeint(num,0); - } - else - { - addr = (num << 2) + idt.base; - - if ((num << 2) + 3 > idt.limit) - { - if (idt.limit < 35) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("Triple fault in real mode - reset\n"); -#endif - } - else - x86_int(8); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - cycles-=70; - CPU_BLOCK_END(); -} - -void x86_int_sw(int num) -{ - uint32_t addr; - flags_rebuild(); - cycles -= timing_int; - if (msw&1) - { - pmodeint(num,1); - } - else - { - addr = (num << 2) + idt.base; - - if ((num << 2) + 3 > idt.limit) - { - x86_int(13); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - cycles -= timing_int_rm; - } - } - trap = 0; - CPU_BLOCK_END(); -} - -int x86_int_sw_rm(int num) -{ - uint32_t addr; - uint16_t new_pc, new_cs; - - flags_rebuild(); - cycles -= timing_int; - - addr = num << 2; - new_pc = readmemw(0, addr); - new_cs = readmemw(0, addr + 2); - - if (cpu_state.abrt) return 1; - - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - if (cpu_state.abrt) { -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("abrt5\n"); -#endif - return 1; - } - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - if (cpu_state.abrt) { -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("abrt6\n"); -#endif - return 1; - } - SP-=6; - - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = new_pc; - loadcs(new_cs); - oxpc=cpu_state.pc; - - cycles -= timing_int_rm; - trap = 0; - CPU_BLOCK_END(); - - return 0; -} - -void x86illegal() -{ - x86_int(6); -} /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. @@ -411,94 +262,6 @@ static void prefetch_flush() #define PREFETCH_FLUSH() prefetch_flush() -int checkio(int port) -{ - uint16_t t; - uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66); - cpl_override = 0; - if (cpu_state.abrt) return 0; - if ((t+(port>>3))>tr.limit) return 1; - cpl_override = 1; - d = readmemb386l(0, tr.base + t + (port >> 3)); - cpl_override = 0; - return d&(1<<(port&7)); -} - -int xout=0; - - -#define divexcp() { \ - x86_int(0); \ -} - -int divl(uint32_t val) -{ - uint64_t num, quo; - uint32_t rem, quo32; - - if (val==0) - { - divexcp(); - return 1; - } - - num=(((uint64_t)EDX)<<32)|EAX; - quo=num/val; - rem=num%val; - quo32=(uint32_t)(quo&0xFFFFFFFF); - - if (quo!=(uint64_t)quo32) - { - divexcp(); - return 1; - } - EDX=rem; - EAX=quo32; - return 0; -} -int idivl(int32_t val) -{ - int64_t num, quo; - int32_t rem, quo32; - - if (val==0) - { - divexcp(); - return 1; - } - - num=(((uint64_t)EDX)<<32)|EAX; - quo=num/val; - rem=num%val; - quo32=(int32_t)(quo&0xFFFFFFFF); - - if (quo!=(int64_t)quo32) - { - divexcp(); - return 1; - } - EDX=rem; - EAX=quo32; - return 0; -} - - -void cpu_386_flags_extract() -{ - flags_extract(); -} -void cpu_386_flags_rebuild() -{ - flags_rebuild(); -} - -int oldi; - -uint32_t testr[9]; -int dontprint=0; - void enter_smm() { uint32_t smram_state = smbase + 0xfe00; @@ -510,6 +273,7 @@ void enter_smm() cpu_state.eflags = 0; in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); smi_latched = 1; mem_writel_phys(smram_state + 0xf8, smbase); @@ -704,6 +468,7 @@ void leave_smm() = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; } + mem_restore_mem_state(smbase, 131072); in_smm = 0; nmi_mask = 1; @@ -716,11 +481,12 @@ void leave_smm() #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(cpu_state.flags & T_FLAG)) +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC static int cycles_main = 0; + void exec386_dynarec(int cycs) { int vector; @@ -1134,10 +900,10 @@ inrecomp=0; } } } - - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + cycles_main -= (cycles_start - cycles); } } diff --git a/src/cpu_common.bak/386_dynarec - Cópia.c b/src/cpu_common.bak/386_dynarec - Cópia.c new file mode 100644 index 000000000..75219e86a --- /dev/null +++ b/src/cpu_common.bak/386_dynarec - Cópia.c @@ -0,0 +1,1008 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; +#endif + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); +#ifdef USE_NEW_DYNAREC + codeblock_t *block = &codeblock[codeblock_hash[hash]]; +#else + codeblock_t *block = codeblock_hash[hash]; +#endif + int valid_block = 0; +#ifdef USE_NEW_DYNAREC + + if (!cpu_state.abrt) +#else + trap = 0; + + if (block && !cpu_state.abrt) +#endif + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); +#ifdef USE_NEW_DYNAREC + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +#else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +#endif + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; +#ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +#endif + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +#ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +#else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +#endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; +#ifdef USE_NEW_DYNAREC + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } +#else + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } +#endif + } +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +#else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +#endif + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +#ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +#else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +#endif + } + } + +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) +#else + if (valid_block && block->was_recompiled) +#endif + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +#ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +#endif + + inrecomp=1; + code(); + inrecomp=0; + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cs+cpu_state.pc; +#ifdef USE_NEW_DYNAREC + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } +#ifdef USE_NEW_DYNAREC + else + cpu_state.oldpc = cpu_state.pc; +#endif + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { +#ifdef USE_NEW_DYNAREC + trap = 0; +#endif + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_new/386_dynarec.c b/src/cpu_common.bak/386_dynarec.c similarity index 99% rename from src/cpu_new/386_dynarec.c rename to src/cpu_common.bak/386_dynarec.c index 0081aceb8..4ca6b4493 100644 --- a/src/cpu_new/386_dynarec.c +++ b/src/cpu_common.bak/386_dynarec.c @@ -9,18 +9,18 @@ # define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" #ifdef USE_DYNAREC #include "codegen.h" #include "codegen_backend.h" @@ -874,10 +874,11 @@ void exec386_dynarec(int cycs) } } } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); } - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); cycles_main -= (cycles_start - cycles); } } diff --git a/src/cpu_common.bak/386_dynarec.c.temp b/src/cpu_common.bak/386_dynarec.c.temp new file mode 100644 index 000000000..78130f3c0 --- /dev/null +++ b/src/cpu_common.bak/386_dynarec.c.temp @@ -0,0 +1,900 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + + if (!use32) cpu_state.pc &= 0xffff; + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + trap = 0; + + if (block && !cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + block = new_block; + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } + } + + if (valid_block && block->was_recompiled) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + + codeblock_hash[hash] = block; + + inrecomp=1; + code(); + inrecomp=0; + if (!use32) cpu_state.pc &= 0xffff; + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { + oldcs=CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + CS = oldcs; +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Double fault %i\n", ins); +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + #ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); + #endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags&I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_new/386_dynarec_ops.c b/src/cpu_common.bak/386_dynarec_ops.c similarity index 95% rename from src/cpu_new/386_dynarec_ops.c rename to src/cpu_common.bak/386_dynarec_ops.c index 1996b5824..80b72d33b 100644 --- a/src/cpu_new/386_dynarec_ops.c +++ b/src/cpu_common.bak/386_dynarec_ops.c @@ -9,15 +9,14 @@ #endif #include "../86box.h" #include "cpu.h" -#include "../timer.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" #include "x86_flags.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" #include "codegen.h" #define CPU_BLOCK_END() cpu_block_end = 1 diff --git a/src/cpu/386_ops.h b/src/cpu_common.bak/386_ops.h similarity index 82% rename from src/cpu/386_ops.h rename to src/cpu_common.bak/386_ops.h index c66b3d0b4..a8213d116 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu_common.bak/386_ops.h @@ -167,7 +167,7 @@ static int ILLEGAL(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686))) static int internal_illegal(char *s) { cpu_state.pc = cpu_state.oldpc; @@ -184,13 +184,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #endif #endif -#include "x86seg.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#include "x86_ops_call.h" #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -220,10 +218,16 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_rep.h" #include "x86_ops_ret.h" #include "x86_ops_set.h" -#include "x86_ops_shift.h" #include "x86_ops_stack.h" #include "x86_ops_string.h" #include "x86_ops_xchg.h" +#include "x86seg.h" +#include "x86_ops_call.h" +#include "x86_ops_shift.h" +#ifdef USE_NEW_DYNAREC +#include "x86_ops_amd.h" +#include "x86_ops_3dnow.h" +#endif static int op0F_w_a16(uint32_t fetchdat) @@ -454,7 +458,7 @@ const OpFn OP_TABLE(486_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -632,6 +636,99 @@ const OpFn OP_TABLE(winchip_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#ifdef USE_NEW_DYNAREC +const OpFn OP_TABLE(winchip2_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; +#endif + const OpFn OP_TABLE(pentium_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -814,7 +911,191 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_NEW_DYNAREC +const OpFn OP_TABLE(k6_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; + +const OpFn OP_TABLE(k62_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; +#endif + +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*16-bit data, 16-bit addr*/ diff --git a/src/cpu_new/808x.c b/src/cpu_common.bak/808x.c similarity index 98% rename from src/cpu_new/808x.c rename to src/cpu_common.bak/808x.c index 686ea9e0c..1904d7322 100644 --- a/src/cpu_new/808x.c +++ b/src/cpu_common.bak/808x.c @@ -9,7 +9,7 @@ * 808x CPU emulation, mostly ported from reenigne's XTCE, which * is cycle-accurate. * - * Version: @(#)808x.c 1.0.9 2019/02/13 + * Version: @(#)808x.c 1.0.11 2019/10/21 * * Authors: Andrew Jenner, * Miran Grca, @@ -23,17 +23,18 @@ #include #include #include + #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" +#include "machine.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" /* The opcode of the instruction currently being executed. */ uint8_t opcode; @@ -235,7 +236,7 @@ clock_end(void) { int diff = cycdiff - cycles; - /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) timer_process(); @@ -257,8 +258,10 @@ fetch_and_bus(int c, int bus) } pfq_add(c, !bus); - clock_end(); - clock_start(); + if (bus < 2) { + clock_end(); + clock_start(); + } } @@ -275,10 +278,13 @@ wait(int c, int bus) void sub_cycles(int c) { + if (c <= 0) + return; + cycles -= c; if (!is286) - fetch_and_bus(c, 1); + fetch_and_bus(c, 2); } @@ -647,6 +653,13 @@ sign_extend(uint8_t data) } +static uint32_t +sign_extend32(uint16_t data) +{ + return data + (data < 0x8000 ? 0 : 0xffff0000); +} + + /* Fetches the effective address from the prefetch queue according to MOD and R/M. */ static void do_mod_rm(void) @@ -912,7 +925,7 @@ reset_common(int hard) if (isibmcpu) cpu_cache_int_enabled = 1; else - cpu_cache_int_enabled = 0; + cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; cpu_state.eflags = 0; @@ -920,6 +933,7 @@ reset_common(int hard) if (AT) { loadcs(0xF000); cpu_state.pc = 0xFFF0; + cpu_state.seg_cs.base = 0xFFFF0000; rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; } else { loadcs(0xFFFF); @@ -950,8 +964,8 @@ reset_common(int hard) if (hard) codegen_reset(); #endif - if (!hard) - flushmmucache(); + if (!hard) + flushmmucache(); x86_was_reset = 1; cpu_alt_reset = 0; @@ -959,6 +973,8 @@ reset_common(int hard) takeint = 0; cpu_ven_reset(); + + cpu_alu_op = 0; } @@ -1754,6 +1770,7 @@ execx86(int cycs) uint8_t temp = 0, temp2; uint16_t addr, tempw; uint16_t new_cs, new_ip; + uint32_t result; int bits; cycles += cycs; @@ -2736,17 +2753,25 @@ execx86(int cycs) case 0x28: /* IMUL */ wait(1, 0); if (opcode & 1) { + result = cpu_data; mul(AX, cpu_data); AX = cpu_data; DX = cpu_dest; cpu_data |= DX; - set_co_mul(DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + result = ((uint32_t) DX << 16) | AX; + if ((rmdat & 0x38) == 0x20) + set_co_mul(DX != 0x0000); + else + set_co_mul(result != sign_extend32(AX)); } else { mul(AL, cpu_data); AL = (uint8_t) cpu_data; AH = (uint8_t) cpu_dest; cpu_data |= AH; - set_co_mul(AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + if ((rmdat & 0x38) == 0x20) + set_co_mul(AH != 0x00); + else + set_co_mul(AX != sign_extend(AL)); } /* NOTE: When implementing the V20, care should be taken to not change the zero flag. */ @@ -2881,6 +2906,8 @@ execx86(int cycs) if (noint) noint = 0; + + cpu_alu_op = 0; } ins++; diff --git a/src/cpu_common.bak/codegen_public.h b/src/cpu_common.bak/codegen_public.h new file mode 100644 index 000000000..c1f16d893 --- /dev/null +++ b/src/cpu_common.bak/codegen_public.h @@ -0,0 +1,62 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen_public.h 1.0.0 2020/01/27 + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef _CODEGEN_PUBLIC_H_ +#define _CODEGEN_PUBLIC_H_ + +#ifndef USE_NEW_DYNAREC +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 +#endif +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 4 + +#ifdef USE_NEW_DYNAREC +#define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_INVALID 0 +#endif + + +extern void codegen_init(); +#ifdef USE_NEW_DYNAREC +extern void codegen_close(); +#endif +extern void codegen_flush(); + + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +extern uint32_t recomp_page; +extern int codegen_in_recompile; + +#endif diff --git a/src/cpu_new/cpu.c b/src/cpu_common.bak/cpu.c similarity index 97% rename from src/cpu_new/cpu.c rename to src/cpu_common.bak/cpu.c index 6b277275c..3ade0e879 100644 --- a/src/cpu_new/cpu.c +++ b/src/cpu_common.bak/cpu.c @@ -42,16 +42,16 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../io.h" +#include "device.h" +#include "machine.h" +#include "86box_io.h" #include "x86_ops.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pci.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "pci.h" #ifdef USE_DYNAREC # include "codegen.h" #endif @@ -75,11 +75,13 @@ enum { CPUID_FXSR = (1 << 24) }; +#ifdef USE_NEW_DYNAREC /*Addition flags returned by CPUID function 0x80000001*/ enum { CPUID_3DNOW = (1 << 31) }; +#endif #ifdef USE_DYNAREC @@ -103,8 +105,10 @@ const OpFn *x86_dynarec_opcodes_df_a16; const OpFn *x86_dynarec_opcodes_df_a32; const OpFn *x86_dynarec_opcodes_REPE; const OpFn *x86_dynarec_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC const OpFn *x86_dynarec_opcodes_3DNOW; #endif +#endif const OpFn *x86_opcodes; const OpFn *x86_opcodes_0f; @@ -126,7 +130,9 @@ const OpFn *x86_opcodes_df_a16; const OpFn *x86_opcodes_df_a32; const OpFn *x86_opcodes_REPE; const OpFn *x86_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC const OpFn *x86_opcodes_3DNOW; +#endif int in_smm = 0, smi_line = 0, smi_latched = 0; uint32_t smbase = 0x30000; @@ -195,13 +201,21 @@ uint64_t ecx1e0_msr = 0; uint64_t ecx570_msr = 0; #endif +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ +#ifdef USE_NEW_DYNAREC uint64_t star = 0; /* AMD K6-2+. */ +#endif -uint64_t amd_efer = 0, amd_whcr = 0, /* AMD K6-2+ registers. */ - amd_uwccr = 0, amd_epmr = 0, +#ifdef USE_NEW_DYNAREC +uint64_t amd_efer = 0, amd_whcr = 0, + amd_uwccr = 0, amd_epmr = 0, /* AMD K6-2+ registers. */ amd_psor = 0, amd_pfir = 0, amd_l2aar = 0; +#else +uint64_t amd_efer = 0, amd_whcr = 0; +#endif +#endif int timing_rr; int timing_mr, timing_mrl; @@ -257,7 +271,7 @@ cpu_set(void) cpu_manufacturer = 0; cpu = 0; } - + cpu_effective = cpu; cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective]; @@ -272,8 +286,14 @@ cpu_set(void) is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); +#else + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86); +#endif + cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); + if (cpu_s->multi) { cpu_busspeed = cpu_s->rspeed / cpu_s->multi; } @@ -315,7 +335,7 @@ cpu_set(void) io_sethandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); else io_removehandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); - + #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); #else @@ -323,12 +343,16 @@ cpu_set(void) #endif x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; +#ifdef USE_NEW_DYNAREC x86_opcodes_3DNOW = ops_3DNOW; +#endif #ifdef USE_DYNAREC x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; +#ifdef USE_NEW_DYNAREC x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; #endif +#endif #ifdef USE_DYNAREC if (hasfpu) @@ -490,7 +514,7 @@ cpu_set(void) timing_jmp_pm = 23; timing_jmp_pm_gate = 38; break; - + case CPU_IBM386SLC: case CPU_386SX: timing_rr = 2; /*register dest - register src*/ @@ -553,7 +577,7 @@ cpu_set(void) timing_jmp_pm = 27; timing_jmp_pm_gate = 45; break; - + case CPU_IBM486SLC: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); @@ -590,6 +614,7 @@ cpu_set(void) timing_jmp_pm_gate = 32; timing_misaligned = 3; break; + case CPU_IBM486BL: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); @@ -941,6 +966,7 @@ cpu_set(void) cpu_cyrix_alignment = 1; break; +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); @@ -982,6 +1008,7 @@ cpu_set(void) cpu_cyrix_alignment = 1; codegen_timing_set(&codegen_timing_winchip2); break; +#endif case CPU_PENTIUM: #ifdef USE_DYNAREC @@ -1069,6 +1096,7 @@ cpu_set(void) #endif break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1237,13 +1265,15 @@ cpu_set(void) #endif ccr4 = 0x80; break; +#endif +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); #else - x86_setopcodes(ops_386, ops_k6_0f); + x86_setopcodes(ops_386, ops_pentiummmx_0f); #endif timing_rr = 1; /*register dest - register src*/ timing_rm = 2; /*register dest - memory src*/ @@ -1277,7 +1307,7 @@ cpu_set(void) cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; -#ifdef USE_DYNAREC +#if defined(USE_NEW_DYNAREC) && defined(USE_DYNAREC) codegen_timing_set(&codegen_timing_k6); #endif break; @@ -1321,10 +1351,16 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_pentium); +#endif #endif break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: case CPU_K6_2C: case CPU_K6_3: @@ -1369,6 +1405,7 @@ cpu_set(void) cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; codegen_timing_set(&codegen_timing_k6); break; +#endif #if defined(DEV_BRANCH) && defined(USE_I686) case CPU_PENTIUMPRO: @@ -1422,7 +1459,11 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_686); +#endif #endif break; @@ -1478,7 +1519,11 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_686); +#endif #endif break; #endif @@ -1534,7 +1579,11 @@ cpu_set(void) msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC codegen_timing_set(&codegen_timing_k6); +#else + codegen_timing_set(&codegen_timing_686); +#endif #endif break; #endif @@ -1667,6 +1716,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: switch (EAX) { @@ -1726,6 +1776,7 @@ cpu_CPUID(void) break; } break; +#endif case CPU_PENTIUM: if (!EAX) @@ -1745,6 +1796,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: if (!EAX) { @@ -1876,7 +1928,9 @@ cpu_CPUID(void) else EAX = EBX = ECX = EDX = 0; break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: case CPU_K6_2C: switch (EAX) @@ -2037,6 +2091,7 @@ cpu_CPUID(void) break; } break; +#endif case CPU_PENTIUMMMX: if (!EAX) @@ -2057,6 +2112,7 @@ cpu_CPUID(void) break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: if (!EAX) { @@ -2132,6 +2188,7 @@ cpu_CPUID(void) else EAX = EBX = ECX = EDX = 0; break; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -2211,6 +2268,7 @@ cpu_CPUID(void) void cpu_ven_reset(void) { +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_K5: @@ -2222,6 +2280,7 @@ void cpu_ven_reset(void) amd_efer = amd_whcr = 0ULL; star = 0ULL; break; +#ifdef USE_NEW_DYNAREC case CPU_K6_2C: amd_efer = 2ULL; amd_whcr = star = 0ULL; @@ -2244,7 +2303,9 @@ void cpu_ven_reset(void) amd_pfir = amd_l2aar = 0ULL; amd_epmr = 0ULL; break; +#endif } +#endif } void cpu_RDMSR() @@ -2252,7 +2313,9 @@ void cpu_RDMSR() switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: +#endif EAX = EDX = 0; switch (ECX) { @@ -2282,6 +2345,7 @@ void cpu_RDMSR() } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -2312,7 +2376,9 @@ void cpu_RDMSR() break; } break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: EAX = EDX = 0; switch (ECX) @@ -2493,6 +2559,7 @@ void cpu_RDMSR() break; } break; +#endif case CPU_PENTIUM: case CPU_PENTIUMMMX: @@ -2505,6 +2572,7 @@ void cpu_RDMSR() break; } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -2517,6 +2585,7 @@ void cpu_RDMSR() break; } break; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -2649,12 +2718,16 @@ i686_invalid_rdmsr: void cpu_WRMSR() { +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t temp; +#endif switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC case CPU_WINCHIP2: +#endif switch (ECX) { case 0x02: @@ -2679,10 +2752,12 @@ void cpu_WRMSR() cpu_features |= CPU_FEATURE_CX8; else cpu_features &= ~CPU_FEATURE_CX8; +#ifdef USE_NEW_DYNAREC if ((EAX & (1 << 20)) && machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) cpu_features |= CPU_FEATURE_3DNOW; else cpu_features &= ~CPU_FEATURE_3DNOW; +#endif if (EAX & (1 << 29)) CPUID = 0; else @@ -2697,6 +2772,7 @@ void cpu_WRMSR() } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -2726,7 +2802,9 @@ void cpu_WRMSR() break; } break; +#endif +#ifdef USE_NEW_DYNAREC case CPU_K6_2: switch (ECX) { @@ -2887,6 +2965,7 @@ void cpu_WRMSR() break; } break; +#endif case CPU_PENTIUM: case CPU_PENTIUMMMX: @@ -2897,6 +2976,7 @@ void cpu_WRMSR() break; } break; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -2908,6 +2988,7 @@ void cpu_WRMSR() break; } break; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -3040,6 +3121,7 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv) if ((ccr3 & 0xf0) == 0x10) { ccr4 = val; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86) { if (val & 0x80) @@ -3047,6 +3129,7 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv) else CPUID = 0; } +#endif } break; case 0xe9: /*CCR5*/ diff --git a/src/cpu/cpu.h b/src/cpu_common.bak/cpu.h similarity index 80% rename from src/cpu/cpu.h rename to src/cpu_common.bak/cpu.h index 12a50473b..38086347a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu_common.bak/cpu.h @@ -18,63 +18,72 @@ * Copyright 2016-2018 leilei. * Copyright 2016,2018 Miran Grca. */ -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/cpu.h" -#else - #ifndef EMU_CPU_H # define EMU_CPU_H +enum { + CPU_8088, /* 808x class CPUs */ + CPU_8086, +#ifdef USE_NEC_808X + CPU_V20, /* NEC 808x class CPUs - future proofing */ + CPU_V30, +#endif + CPU_286, /* 286 class CPUs */ + CPU_386SX, /* 386 class CPUs */ + CPU_386DX, + CPU_IBM386SLC, + CPU_IBM486SLC, + CPU_IBM486BL, + CPU_RAPIDCAD, + CPU_486SLC, + CPU_486DLC, + CPU_i486SX, /* 486 class CPUs */ + CPU_Am486SX, + CPU_Cx486S, + CPU_i486DX, + CPU_Am486DX, + CPU_Cx486DX, + CPU_iDX4, + CPU_Cx5x86, + CPU_WINCHIP, /* 586 class CPUs */ +#ifdef USE_NEW_DYNAREC + CPU_WINCHIP2, +#endif + CPU_PENTIUM, + CPU_PENTIUMMMX, +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + CPU_Cx6x86, + CPU_Cx6x86MX, + CPU_Cx6x86L, + CPU_CxGX1, +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) + CPU_K5, + CPU_5K86, + CPU_K6, +#endif +#ifdef USE_NEW_DYNAREC + CPU_K6_2, + CPU_K6_2C, + CPU_K6_3, + CPU_K6_2P, + CPU_K6_3P, +#endif +#if defined(DEV_BRANCH) && defined(USE_I686) + CPU_PENTIUMPRO, /* 686 class CPUs */ +#ifdef USE_PENTIUM2 + CPU_PENTIUM2, +#endif + CPU_PENTIUM2D, +#endif + CPU_MAX /* Only really needed to close the enum in a way independent of the #ifdef's. */ +}; -#define CPU_8088 0 /* 808x class CPUs */ -#define CPU_8086 1 -#define CPU_286 2 /* 286 class CPUs */ -#define CPU_386SX 3 /* 386 class CPUs */ -#define CPU_386DX 4 -#define CPU_IBM386SLC 5 -#define CPU_IBM486SLC 6 -#define CPU_IBM486BL 7 -#define CPU_RAPIDCAD 8 -#define CPU_486SLC 9 -#define CPU_486DLC 10 -#define CPU_i486SX 11 /* 486 class CPUs */ -#define CPU_Am486SX 12 -#define CPU_Cx486S 13 -#define CPU_i486DX 14 -#define CPU_Am486DX 15 -#define CPU_Cx486DX 16 -#define CPU_iDX4 17 -#define CPU_Cx5x86 18 -#define CPU_WINCHIP 19 /* 586 class CPUs */ -#define CPU_PENTIUM 20 -#define CPU_PENTIUMMMX 21 -#define CPU_Cx6x86 22 -#define CPU_Cx6x86MX 23 -#define CPU_Cx6x86L 24 -#define CPU_CxGX1 25 -#ifdef DEV_BRANCH -#ifdef USE_AMD_K -#define CPU_K5 26 -#define CPU_5K86 27 -#define CPU_K6 28 -#endif -#endif -#ifdef DEV_BRANCH -#ifdef USE_I686 -#define CPU_PENTIUMPRO 29 /* 686 class CPUs */ -#if 0 -# define CPU_PENTIUM2 30 -# define CPU_PENTIUM2D 31 -#else -# define CPU_PENTIUM2D 30 -#endif -#endif -#endif - #define MANU_INTEL 0 #define MANU_AMD 1 #define MANU_CYRIX 2 #define MANU_IDT 3 +#define MANU_NEC 4 #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 @@ -96,6 +105,7 @@ typedef struct { int8_t atclk_div; } CPU; + extern CPU cpus_8088[]; extern CPU cpus_8086[]; extern CPU cpus_286[]; @@ -115,30 +125,33 @@ extern CPU cpus_i486[]; extern CPU cpus_Am486[]; extern CPU cpus_Cx486[]; extern CPU cpus_WinChip[]; +#ifdef USE_NEW_DYNAREC +extern CPU cpus_WinChip_SS7[]; +#endif extern CPU cpus_Pentium5V[]; extern CPU cpus_Pentium5V50[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium3V[]; extern CPU cpus_Pentium[]; -#ifdef DEV_BRANCH -#ifdef USE_AMD_K +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) extern CPU cpus_K5[]; extern CPU cpus_K56[]; #endif +#ifdef USE_NEW_DYNAREC +extern CPU cpus_K56_SS7[]; #endif -#ifdef DEV_BRANCH -#ifdef USE_CYRIX_6X86 +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) extern CPU cpus_6x863V[]; extern CPU cpus_6x86[]; #endif +#ifdef USE_NEW_DYNAREC +extern CPU cpus_6x86SS7[]; #endif -#ifdef DEV_BRANCH -#ifdef USE_I686 +#if defined(DEV_BRANCH) && defined(USE_I686) extern CPU cpus_PentiumPro[]; extern CPU cpus_Pentium2[]; extern CPU cpus_Pentium2D[]; #endif -#endif #define C_FLAG 0x0001 @@ -196,6 +209,9 @@ typedef union { int16_t sw[4]; uint8_t b[8]; int8_t sb[8]; +#ifdef USE_NEW_DYNAREC + float f[2]; +#endif } MMX_REG; typedef struct { @@ -259,6 +275,16 @@ struct _cpustate_ { new_npxc; uint32_t last_ea; +#ifdef USE_NEW_DYNAREC + uint32_t old_fp_control, new_fp_control; +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ + uint16_t old_fp_control2, new_fp_control2; +#endif +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ + uint32_t trunc_fp_control; +#endif +#endif + x86seg seg_cs, seg_ds, seg_es, @@ -279,9 +305,15 @@ struct _cpustate_ { /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ +#ifdef USE_NEW_DYNAREC +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_MASK 0xff00 +#else #define CPU_STATUS_NOTFLATDS (1 << 16) #define CPU_STATUS_NOTFLATSS (1 << 17) #define CPU_STATUS_MASK 0xffff0000 +#endif #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ @@ -355,12 +387,16 @@ extern int hasfpu; #define CPU_FEATURE_CX8 (1 << 5) #define CPU_FEATURE_3DNOW (1 << 6) -extern uint32_t cpu_features; +extern uint32_t cpu_features; -extern int in_smm, smi_line, smi_latched; -extern uint32_t smbase; +extern int in_smm, smi_line, smi_latched; +extern uint32_t smbase; +#ifdef USE_NEW_DYNAREC +extern uint16_t cpu_cur_status; +#else extern uint32_t cpu_cur_status; +#endif extern uint64_t cpu_CR4_mask; extern uint64_t tsc; extern msr_t msr; @@ -455,8 +491,14 @@ extern CPU cpus_acer[]; // FIXME: should be in machine file! /* Functions. */ extern int cpu_has_feature(int feature); +#ifdef USE_NEW_DYNAREC +extern void loadseg_dynarec(uint16_t seg, x86seg *s); +extern int loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); +#else extern void loadseg(uint16_t seg, x86seg *s); extern void loadcs(uint16_t seg); +#endif extern char *cpu_current_pc(char *bufp); @@ -473,16 +515,24 @@ extern void codegen_reset(void); extern void cpu_set_edx(void); extern int divl(uint32_t val); extern void execx86(int cycs); -extern void enter_smm(); -extern void leave_smm(); +extern void enter_smm(); +extern void leave_smm(); extern void exec386(int cycs); extern void exec386_dynarec(int cycs); extern int idivl(int32_t val); +#ifdef USE_NEW_DYNAREC +extern void loadcscall(uint16_t seg, uint32_t old_pc); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +#else extern void loadcscall(uint16_t seg); extern void loadcsjmp(uint16_t seg, uint32_t old_pc); extern void pmodeint(int num, int soft); extern void pmoderetf(int is32, uint16_t off); extern void pmodeiret(int is32); +#endif extern void resetmcr(void); extern void resetx86(void); extern void refreshread(void); @@ -509,4 +559,3 @@ extern void cpu_ven_reset(void); #endif /*EMU_CPU_H*/ -#endif diff --git a/src/cpu_new/cpu_table.c b/src/cpu_common.bak/cpu_table.c similarity index 98% rename from src/cpu_new/cpu_table.c rename to src/cpu_common.bak/cpu_table.c index 34767b870..1e7a3ffba 100644 --- a/src/cpu_new/cpu_table.c +++ b/src/cpu_common.bak/cpu_table.c @@ -45,9 +45,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../machine/machine.h" +#include "machine.h" CPU cpus_8088[] = { @@ -55,10 +55,10 @@ CPU cpus_8088[] = { {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 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} + {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 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} }; CPU cpus_pcjr[] = { @@ -153,7 +153,6 @@ CPU cpus_i386DX[] = { {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; @@ -226,6 +225,7 @@ CPU cpus_486DLC[] = { {"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} }; + CPU cpus_i486S1[] = { /*i486*/ {"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, @@ -249,7 +249,7 @@ CPU cpus_Am486S1[] = { {"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Am486SX/40", CPU_Am486SX, 40000000, 1, 40000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ {"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Am486DX/40", CPU_Am486DX, 40000000, 1, 40000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, @@ -284,8 +284,8 @@ CPU cpus_i486[] = { {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/ {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, {"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, - {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, - {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, @@ -328,13 +328,14 @@ CPU cpus_Cx486[] = { {"Cx486DX4/100", CPU_Cx486DX, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, /*Cyrix 5x86*/ - {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/ {"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, {"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, {"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) CPU cpus_6x863V[] = { /*Cyrix 6x86*/ {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, @@ -370,7 +371,9 @@ CPU cpus_6x86[] = { {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif +#ifdef USE_NEW_DYNAREC CPU cpus_6x86SS7[] = { /*Cyrix 6x86*/ {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, @@ -398,6 +401,7 @@ CPU cpus_6x86[] = { {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif CPU cpus_WinChip[] = { /*IDT WinChip*/ @@ -412,15 +416,18 @@ CPU cpus_WinChip[] = { {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, +#ifdef USE_NEW_DYNAREC {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, +#endif {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#ifdef USE_NEW_DYNAREC CPU cpus_WinChip_SS7[] = { /*IDT WinChip*/ {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, @@ -444,6 +451,7 @@ CPU cpus_WinChip_SS7[] = { {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ @@ -528,6 +536,8 @@ CPU cpus_Pentium[] = { {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + + /*Mobile Pentium*/ {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, @@ -548,6 +558,8 @@ CPU cpus_Pentium[] = { {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) CPU cpus_K5[] = { /*AMD K5 (Socket 5)*/ {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, @@ -586,13 +598,17 @@ CPU cpus_K56[] = { {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, +#ifdef USE_NEW_DYNAREC {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, {"K6-2/366", CPU_K6_2, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, +#endif {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif +#ifdef USE_NEW_DYNAREC CPU cpus_K56_SS7[] = { /*AMD K5 (Socket 7)*/ {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, @@ -645,6 +661,7 @@ CPU cpus_K56_SS7[] = { {"K6-III+/500", CPU_K6_3P, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 diff --git a/src/cpu_new/x86.h b/src/cpu_common.bak/x86.h similarity index 100% rename from src/cpu_new/x86.h rename to src/cpu_common.bak/x86.h diff --git a/src/cpu_new/x86_ops.h b/src/cpu_common.bak/x86_ops.h similarity index 95% rename from src/cpu_new/x86_ops.h rename to src/cpu_common.bak/x86_ops.h index 0de3b3252..652bdd29f 100644 --- a/src/cpu_new/x86_ops.h +++ b/src/cpu_common.bak/x86_ops.h @@ -70,7 +70,9 @@ extern const OpFn *x86_dynarec_opcodes_df_a16; extern const OpFn *x86_dynarec_opcodes_df_a32; extern const OpFn *x86_dynarec_opcodes_REPE; extern const OpFn *x86_dynarec_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC extern const OpFn *x86_dynarec_opcodes_3DNOW; +#endif extern const OpFn dynarec_ops_286[1024]; extern const OpFn dynarec_ops_286_0f[1024]; @@ -81,14 +83,21 @@ extern const OpFn dynarec_ops_386_0f[1024]; extern const OpFn dynarec_ops_486_0f[1024]; extern const OpFn dynarec_ops_winchip_0f[1024]; +#ifdef USE_NEW_DYNAREC extern const OpFn dynarec_ops_winchip2_0f[1024]; +#endif extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -extern const OpFn dynarec_ops_c6x86mx_0f[1024]; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) +extern const OpFn dynarec_ops_c6x86mx_0f[1024]; +#endif + +#ifdef USE_NEW_DYNAREC extern const OpFn dynarec_ops_k6_0f[1024]; extern const OpFn dynarec_ops_k62_0f[1024]; +#endif #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn dynarec_ops_pentiumpro_0f[1024]; @@ -138,7 +147,9 @@ extern const OpFn dynarec_ops_fpu_686_df_a32[256]; extern const OpFn dynarec_ops_REPE[1024]; extern const OpFn dynarec_ops_REPNE[1024]; +#ifdef USE_NEW_DYNAREC extern const OpFn dynarec_ops_3DNOW[256]; +#endif #else void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); #endif @@ -163,7 +174,9 @@ extern const OpFn *x86_opcodes_df_a16; extern const OpFn *x86_opcodes_df_a32; extern const OpFn *x86_opcodes_REPE; extern const OpFn *x86_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC extern const OpFn *x86_opcodes_3DNOW; +#endif extern const OpFn ops_286[1024]; extern const OpFn ops_286_0f[1024]; @@ -174,15 +187,21 @@ extern const OpFn ops_386_0f[1024]; extern const OpFn ops_486_0f[1024]; extern const OpFn ops_winchip_0f[1024]; +#ifdef USE_NEW_DYNAREC extern const OpFn ops_winchip2_0f[1024]; +#endif extern const OpFn ops_pentium_0f[1024]; extern const OpFn ops_pentiummmx_0f[1024]; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) extern const OpFn ops_c6x86mx_0f[1024]; +#endif +#ifdef USE_NEW_DYNAREC extern const OpFn ops_k6_0f[1024]; extern const OpFn ops_k62_0f[1024]; +#endif #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn ops_pentiumpro_0f[1024]; @@ -232,7 +251,9 @@ extern const OpFn ops_fpu_686_df_a32[256]; extern const OpFn ops_REPE[1024]; extern const OpFn ops_REPNE[1024]; +#ifdef USE_NEW_DYNAREC extern const OpFn ops_3DNOW[256]; +#endif #define C0 (1<<8) #define C1 (1<<9) diff --git a/src/cpu_new/x86_ops_3dnow.h b/src/cpu_common.bak/x86_ops_3dnow.h similarity index 100% rename from src/cpu_new/x86_ops_3dnow.h rename to src/cpu_common.bak/x86_ops_3dnow.h diff --git a/src/cpu_new/x86_ops_amd.h b/src/cpu_common.bak/x86_ops_amd.h similarity index 100% rename from src/cpu_new/x86_ops_amd.h rename to src/cpu_common.bak/x86_ops_amd.h diff --git a/src/cpu_new/x86_ops_arith.h b/src/cpu_common.bak/x86_ops_arith.h similarity index 100% rename from src/cpu_new/x86_ops_arith.h rename to src/cpu_common.bak/x86_ops_arith.h diff --git a/src/cpu_new/x86_ops_atomic.h b/src/cpu_common.bak/x86_ops_atomic.h similarity index 100% rename from src/cpu_new/x86_ops_atomic.h rename to src/cpu_common.bak/x86_ops_atomic.h diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu_common.bak/x86_ops_bcd.h similarity index 100% rename from src/cpu/x86_ops_bcd.h rename to src/cpu_common.bak/x86_ops_bcd.h diff --git a/src/cpu_new/x86_ops_bit.h b/src/cpu_common.bak/x86_ops_bit.h similarity index 100% rename from src/cpu_new/x86_ops_bit.h rename to src/cpu_common.bak/x86_ops_bit.h diff --git a/src/cpu/x86_ops_bitscan.h b/src/cpu_common.bak/x86_ops_bitscan.h similarity index 100% rename from src/cpu/x86_ops_bitscan.h rename to src/cpu_common.bak/x86_ops_bitscan.h diff --git a/src/cpu_new/x86_ops_flag.h b/src/cpu_common.bak/x86_ops_flag.h similarity index 100% rename from src/cpu_new/x86_ops_flag.h rename to src/cpu_common.bak/x86_ops_flag.h diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu_common.bak/x86_ops_fpu.h similarity index 100% rename from src/cpu/x86_ops_fpu.h rename to src/cpu_common.bak/x86_ops_fpu.h diff --git a/src/cpu_new/x86_ops_i686.h b/src/cpu_common.bak/x86_ops_i686.h similarity index 98% rename from src/cpu_new/x86_ops_i686.h rename to src/cpu_common.bak/x86_ops_i686.h index b4c1ed7ff..2b34e0822 100644 --- a/src/cpu_new/x86_ops_i686.h +++ b/src/cpu_common.bak/x86_ops_i686.h @@ -8,10 +8,10 @@ * * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. * - * Version: @(#)x86_ops_i686.h 1.0.5 2018/10/17 + * Version: @(#)x86_ops_i686.h 1.0.6 2020/01/27 * * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ /* 0 = Limit 0-15 @@ -190,10 +190,14 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -316,7 +320,9 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; @@ -371,10 +377,14 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -497,7 +507,9 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; diff --git a/src/cpu/x86_ops_inc_dec.h b/src/cpu_common.bak/x86_ops_inc_dec.h similarity index 100% rename from src/cpu/x86_ops_inc_dec.h rename to src/cpu_common.bak/x86_ops_inc_dec.h diff --git a/src/cpu/x86_ops_int.h b/src/cpu_common.bak/x86_ops_int.h similarity index 100% rename from src/cpu/x86_ops_int.h rename to src/cpu_common.bak/x86_ops_int.h diff --git a/src/cpu/x86_ops_io.h b/src/cpu_common.bak/x86_ops_io.h similarity index 100% rename from src/cpu/x86_ops_io.h rename to src/cpu_common.bak/x86_ops_io.h diff --git a/src/cpu_new/x86_ops_jump.h b/src/cpu_common.bak/x86_ops_jump.h similarity index 100% rename from src/cpu_new/x86_ops_jump.h rename to src/cpu_common.bak/x86_ops_jump.h diff --git a/src/cpu/x86_ops_misc.h b/src/cpu_common.bak/x86_ops_misc.h similarity index 100% rename from src/cpu/x86_ops_misc.h rename to src/cpu_common.bak/x86_ops_misc.h diff --git a/src/cpu_new/x86_ops_mmx.h b/src/cpu_common.bak/x86_ops_mmx.h similarity index 100% rename from src/cpu_new/x86_ops_mmx.h rename to src/cpu_common.bak/x86_ops_mmx.h diff --git a/src/cpu_new/x86_ops_mmx_arith.h b/src/cpu_common.bak/x86_ops_mmx_arith.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_arith.h rename to src/cpu_common.bak/x86_ops_mmx_arith.h diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu_common.bak/x86_ops_mmx_cmp.h similarity index 100% rename from src/cpu/x86_ops_mmx_cmp.h rename to src/cpu_common.bak/x86_ops_mmx_cmp.h diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu_common.bak/x86_ops_mmx_logic.h similarity index 100% rename from src/cpu/x86_ops_mmx_logic.h rename to src/cpu_common.bak/x86_ops_mmx_logic.h diff --git a/src/cpu_new/x86_ops_mmx_mov.h b/src/cpu_common.bak/x86_ops_mmx_mov.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_mov.h rename to src/cpu_common.bak/x86_ops_mmx_mov.h diff --git a/src/cpu_new/x86_ops_mmx_pack.h b/src/cpu_common.bak/x86_ops_mmx_pack.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_pack.h rename to src/cpu_common.bak/x86_ops_mmx_pack.h diff --git a/src/cpu_new/x86_ops_mmx_shift.h b/src/cpu_common.bak/x86_ops_mmx_shift.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_shift.h rename to src/cpu_common.bak/x86_ops_mmx_shift.h diff --git a/src/cpu_new/x86_ops_mov.h b/src/cpu_common.bak/x86_ops_mov.h similarity index 100% rename from src/cpu_new/x86_ops_mov.h rename to src/cpu_common.bak/x86_ops_mov.h diff --git a/src/cpu_new/x86_ops_mov_ctrl.h b/src/cpu_common.bak/x86_ops_mov_ctrl.h similarity index 100% rename from src/cpu_new/x86_ops_mov_ctrl.h rename to src/cpu_common.bak/x86_ops_mov_ctrl.h diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu_common.bak/x86_ops_mov_seg.h similarity index 100% rename from src/cpu/x86_ops_mov_seg.h rename to src/cpu_common.bak/x86_ops_mov_seg.h diff --git a/src/cpu/x86_ops_movx.h b/src/cpu_common.bak/x86_ops_movx.h similarity index 100% rename from src/cpu/x86_ops_movx.h rename to src/cpu_common.bak/x86_ops_movx.h diff --git a/src/cpu/x86_ops_msr.h b/src/cpu_common.bak/x86_ops_msr.h similarity index 100% rename from src/cpu/x86_ops_msr.h rename to src/cpu_common.bak/x86_ops_msr.h diff --git a/src/cpu/x86_ops_mul.h b/src/cpu_common.bak/x86_ops_mul.h similarity index 100% rename from src/cpu/x86_ops_mul.h rename to src/cpu_common.bak/x86_ops_mul.h diff --git a/src/cpu_new/x86_ops_pmode.h b/src/cpu_common.bak/x86_ops_pmode.h similarity index 100% rename from src/cpu_new/x86_ops_pmode.h rename to src/cpu_common.bak/x86_ops_pmode.h diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu_common.bak/x86_ops_prefix.h similarity index 100% rename from src/cpu/x86_ops_prefix.h rename to src/cpu_common.bak/x86_ops_prefix.h diff --git a/src/cpu/x86_ops_rep.h b/src/cpu_common.bak/x86_ops_rep.h similarity index 100% rename from src/cpu/x86_ops_rep.h rename to src/cpu_common.bak/x86_ops_rep.h diff --git a/src/cpu/x86_ops_ret.h b/src/cpu_common.bak/x86_ops_ret.h similarity index 96% rename from src/cpu/x86_ops_ret.h rename to src/cpu_common.bak/x86_ops_ret.h index 75419e6d8..1ebe67b9c 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu_common.bak/x86_ops_ret.h @@ -1,10 +1,16 @@ +#ifdef USE_NEW_DYNAREC +#define CPU_SET_OXPC +#else +#define CPU_SET_OXPC oxpc = cpu_state.pc; +#endif + #define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(0, stack_offset); \ return 1; \ } \ - oxpc = cpu_state.pc; \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmemw(ss, ESP); \ @@ -15,18 +21,18 @@ cpu_state.pc = readmemw(ss, SP); \ loadcs(readmemw(ss, SP + 2)); \ } \ - if (cpu_state.abrt) return 1; \ + if (cpu_state.abrt) return 1; \ if (stack32) ESP += 4 + stack_offset; \ else SP += 4 + stack_offset; \ cycles -= timing_retf_rm; #define RETF_a32(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(1, stack_offset); \ return 1; \ } \ - oxpc = cpu_state.pc; \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmeml(ss, ESP); \ @@ -108,7 +114,7 @@ static int opIRET_286(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -184,7 +190,7 @@ static int opIRET(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -230,7 +236,7 @@ static int opIRETD(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmeml(ss, ESP); diff --git a/src/cpu/x86_ops_set.h b/src/cpu_common.bak/x86_ops_set.h similarity index 100% rename from src/cpu/x86_ops_set.h rename to src/cpu_common.bak/x86_ops_set.h diff --git a/src/cpu_new/x86_ops_stack.h b/src/cpu_common.bak/x86_ops_stack.h similarity index 100% rename from src/cpu_new/x86_ops_stack.h rename to src/cpu_common.bak/x86_ops_stack.h diff --git a/src/cpu_new/x86_ops_string.h b/src/cpu_common.bak/x86_ops_string.h similarity index 100% rename from src/cpu_new/x86_ops_string.h rename to src/cpu_common.bak/x86_ops_string.h diff --git a/src/cpu_new/x86_ops_xchg.h b/src/cpu_common.bak/x86_ops_xchg.h similarity index 100% rename from src/cpu_new/x86_ops_xchg.h rename to src/cpu_common.bak/x86_ops_xchg.h diff --git a/src/cpu/x86seg.h b/src/cpu_common.bak/x86seg.h similarity index 100% rename from src/cpu/x86seg.h rename to src/cpu_common.bak/x86seg.h diff --git a/src/cpu_new/x87.c b/src/cpu_common.bak/x87.c similarity index 98% rename from src/cpu_new/x87.c rename to src/cpu_common.bak/x87.c index 7d27e29f3..367948656 100644 --- a/src/cpu_new/x87.c +++ b/src/cpu_common.bak/x87.c @@ -21,12 +21,12 @@ int fpu_do_log = ENABLE_FPU_LOG; -void +static void fpu_log(const char *fmt, ...) { va_list ap; - if (fpu_do_log) { + if (fpu_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); diff --git a/src/cpu_new/x87.h b/src/cpu_common.bak/x87.h similarity index 100% rename from src/cpu_new/x87.h rename to src/cpu_common.bak/x87.h diff --git a/src/cpu_new/x87_ops.h b/src/cpu_common.bak/x87_ops.h similarity index 100% rename from src/cpu_new/x87_ops.h rename to src/cpu_common.bak/x87_ops.h diff --git a/src/cpu_new/x87_ops_arith.h b/src/cpu_common.bak/x87_ops_arith.h similarity index 100% rename from src/cpu_new/x87_ops_arith.h rename to src/cpu_common.bak/x87_ops_arith.h diff --git a/src/cpu_new/x87_ops_loadstore.h b/src/cpu_common.bak/x87_ops_loadstore.h similarity index 100% rename from src/cpu_new/x87_ops_loadstore.h rename to src/cpu_common.bak/x87_ops_loadstore.h diff --git a/src/cpu_new/x87_ops_misc.h b/src/cpu_common.bak/x87_ops_misc.h similarity index 100% rename from src/cpu_new/x87_ops_misc.h rename to src/cpu_common.bak/x87_ops_misc.h diff --git a/src/cpu_common/386.c b/src/cpu_common/386.c new file mode 100644 index 000000000..416f9577e --- /dev/null +++ b/src/cpu_common/386.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "x86.h" +#include "x87.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" +#include "386_common.h" +#ifdef USE_NEW_DYNAREC +#include "codegen.h" +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + + +extern int codegen_flags_changed; + +int tempc, oldcpl, optype, inttype, oddeven = 0; +int timetolive; + +uint16_t oldcs; + +uint32_t oldds, oldss, olddslimit, oldsslimit, + olddslimitw, oldsslimitw; +uint32_t oxpc; +uint32_t rmdat32; +uint32_t backupregs[16]; + +x86seg _oldds; + + +#ifdef ENABLE_386_LOG +int x386_do_log = ENABLE_386_LOG; + + +void +x386_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_log(fmt, ...) +#endif + + +#undef CPU_BLOCK_END +#define CPU_BLOCK_END() + +static inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; +// pc++; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +static inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 + +#include "x86_flags.h" + +#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ +#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 +#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ +#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + + +#define OP_TABLE(name) ops_ ## name + +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "x86_ops.h" + +void +exec386(int cycs) +{ + // uint8_t opcode; + int vector, tempi, cycdiff, oldcyc; + int cycle_period, ins_cycles; + uint32_t addr; + + cycles += cycs; + + while (cycles > 0) { + cycle_period = (timer_target - (uint32_t)tsc) + 1; + + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; + +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl=CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + +#ifndef USE_NEW_DYNAREC + x86_was_reset = 0; +#endif + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + cpu_state.pc = cpu_state.oldpc; + x386_log("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_LOG + x386_log("Triple fault - reset\n"); +#endif + } + } + } + + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff = oldcyc - cycles; + + if (trap) { + flags_rebuild(); + if (msw&1) + pmodeint(1,0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } + } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } + + ins++; + + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process(); + } + } +} diff --git a/src/cpu_common/386_common.c b/src/cpu_common/386_common.c new file mode 100644 index 000000000..cb140c41a --- /dev/null +++ b/src/cpu_common/386_common.c @@ -0,0 +1,309 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "x86.h" +#include "x87.h" +#include "nmi.h" +#include "mem.h" +#include "pic.h" +#include "pit.h" +#include "fdd.h" +#include "fdc.h" +#include "386_common.h" +#include "x86_flags.h" +#include "codegen.h" + +x86seg gdt, ldt, idt, tr; + +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; + +uint32_t use32; +int stack32; +int optype; + +int trap; + +uint32_t rmdat; + +uint32_t *eal_r, *eal_w; + +int nmi_enable = 1; + +int cpl_override=0; + +int fpucount=0; + +#ifdef USE_NEW_DYNAREC +uint16_t cpu_cur_status = 0; +#else +uint32_t cpu_cur_status = 0; +#endif + +uint32_t pccache; +uint8_t *pccache2; + + +#ifdef ENABLE_386_COMMON_LOG +int x386_common_do_log = ENABLE_386_COMMON_LOG; + + +void +x386_common_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_common_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_common_log(fmt, ...) +#endif + + +void x86_int(int num) +{ + uint32_t addr; + flags_rebuild(); + cpu_state.pc=cpu_state.oldpc; + if (msw&1) + { + pmodeint(num,0); + } + else + { + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) + { + if (idt.limit < 35) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_COMMON_LOG + x386_log("Triple fault in real mode - reset\n"); +#endif + } + else + x86_int(8); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,cpu_state.flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } + + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + cycles-=70; + CPU_BLOCK_END(); +} + +void x86_int_sw(int num) +{ + uint32_t addr; + flags_rebuild(); + cycles -= timing_int; + if (msw&1) + { + pmodeint(num,1); + } + else + { + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) + { + x86_int(13); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,cpu_state.flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } + + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + cycles -= timing_int_rm; + } + } + trap = 0; + CPU_BLOCK_END(); +} + +int x86_int_sw_rm(int num) +{ + uint32_t addr; + uint16_t new_pc, new_cs; + + flags_rebuild(); + cycles -= timing_int; + + addr = num << 2; + new_pc = readmemw(0, addr); + new_cs = readmemw(0, addr + 2); + + if (cpu_state.abrt) return 1; + + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + if (cpu_state.abrt) + return 1; + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + if (cpu_state.abrt) + return 1; + SP-=6; + + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = new_pc; + loadcs(new_cs); +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + + cycles -= timing_int_rm; + trap = 0; + CPU_BLOCK_END(); + + return 0; +} + +void x86illegal() +{ + x86_int(6); +} + +int checkio(int port) +{ + uint16_t t; + uint8_t d; + cpl_override = 1; + t = readmemw(tr.base, 0x66); + cpl_override = 0; + if (cpu_state.abrt) return 0; + if ((t+(port>>3))>tr.limit) return 1; + cpl_override = 1; +#ifdef USE_NEW_DYNAREC + d = readmembl(tr.base + t + (port >> 3)); +#else + d = readmemb386l(0, tr.base + t + (port >> 3)); +#endif + cpl_override = 0; + return d&(1<<(port&7)); +} + +#define divexcp() { \ + x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ + x86_int(0); \ +} + +int divl(uint32_t val) +{ + uint64_t num, quo; + uint32_t rem, quo32; + + if (val==0) + { + divexcp(); + return 1; + } + + num=(((uint64_t)EDX)<<32)|EAX; + quo=num/val; + rem=num%val; + quo32=(uint32_t)(quo&0xFFFFFFFF); + + if (quo!=(uint64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} +int idivl(int32_t val) +{ + int64_t num, quo; + int32_t rem, quo32; + + if (val==0) + { + divexcp(); + return 1; + } + + num=(((uint64_t)EDX)<<32)|EAX; + quo=num/val; + rem=num%val; + quo32=(int32_t)(quo&0xFFFFFFFF); + + if (quo!=(int64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} + + +void cpu_386_flags_extract() +{ + flags_extract(); +} +void cpu_386_flags_rebuild() +{ + flags_rebuild(); +} diff --git a/src/cpu/386_common.h b/src/cpu_common/386_common.h similarity index 77% rename from src/cpu/386_common.h rename to src/cpu_common/386_common.h index 428bf3118..2ab8157a2 100644 --- a/src/cpu/386_common.h +++ b/src/cpu_common/386_common.h @@ -16,6 +16,20 @@ * Copyright 2016-2019 Miran Grca. */ +#ifndef _386_COMMON_H_ +#define _386_COMMON_H_ + +#ifdef USE_NEW_DYNAREC +#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) + +#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#else #undef readmemb #undef writememb @@ -28,8 +42,24 @@ #define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v #define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#endif +int checkio(int port); + + +#ifdef USE_NEW_DYNAREC +#define check_io_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \ + { \ + int tempi = checkio(port); \ + if (cpu_state.abrt) return 1; \ + if (tempi) \ + { \ + x86gpf("check_io_perm(): no permission",0); \ + return 1; \ + } \ + } +#else #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ { \ int tempi = checkio(port); \ @@ -40,6 +70,7 @@ return 1; \ } \ } +#endif #define SEG_CHECK_READ(seg) \ do \ @@ -205,7 +236,6 @@ static __inline uint32_t fastreadl(uint32_t a) return 0; pccache2 = t; pccache=a>>12; - /* return *((uint32_t *)&pccache2[a]); */ } return *((uint32_t *)&pccache2[a]); } @@ -309,19 +339,36 @@ static __inline void seteaq(uint64_t v) { if (seteaq_cwc()) return; +#ifdef USE_NEW_DYNAREC + writememql(easeg + cpu_state.eaaddr, v); +#else writememql(easeg, cpu_state.eaaddr, v); +#endif } +#ifdef USE_NEW_DYNAREC +#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v +#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v +#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +#else #define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else { writememb386l(easeg,cpu_state.eaaddr,v); } } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v #define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else { writememwl(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].w=v #define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else { writememll(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].l=v +#endif - +#ifdef USE_NEW_DYNAREC +#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); +#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); +#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); +#else #define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); #define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v); #define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); - +#endif + #define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ #define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 #define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ #define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + +#endif diff --git a/src/cpu_common/386_dynarec - Cópia (2).c b/src/cpu_common/386_dynarec - Cópia (2).c new file mode 100644 index 000000000..421381dd3 --- /dev/null +++ b/src/cpu_common/386_dynarec - Cópia (2).c @@ -0,0 +1,910 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + + cycdiff=0; + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { + oldcs=CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + + if (!use32) cpu_state.pc &= 0xffff; + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + +/* if (ssegs) + { + ds=oldds; + ss=oldss; + ssegs=0; + }*/ + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + +/* if ((cs + pc) == 4) + fatal("4\n");*/ +/* if (ins >= 141400000) + output = 3;*/ + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + trap = 0; + + if (block && !cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + block = new_block; + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } + } + + if (valid_block && block->was_recompiled) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + + codeblock_hash[hash] = block; + +inrecomp=1; + code(); +inrecomp=0; + if (!use32) cpu_state.pc &= 0xffff; + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { + oldcs=CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { + oldcs=CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + CS = oldcs; + cpu_state.pc = cpu_state.oldpc; +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Double fault %i\n", ins); +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + if (trap) + { + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags&=~I_FLAG; + cpu_state.flags&=~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags&I_FLAG) && pic_intpending) + { + vector=picinterrupt(); + if (vector!=-1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags&=~I_FLAG; + cpu_state.flags&=~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_common/386_dynarec - Cópia.c b/src/cpu_common/386_dynarec - Cópia.c new file mode 100644 index 000000000..75219e86a --- /dev/null +++ b/src/cpu_common/386_dynarec - Cópia.c @@ -0,0 +1,1008 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; +#endif + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); +#ifdef USE_NEW_DYNAREC + codeblock_t *block = &codeblock[codeblock_hash[hash]]; +#else + codeblock_t *block = codeblock_hash[hash]; +#endif + int valid_block = 0; +#ifdef USE_NEW_DYNAREC + + if (!cpu_state.abrt) +#else + trap = 0; + + if (block && !cpu_state.abrt) +#endif + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); +#ifdef USE_NEW_DYNAREC + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +#else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +#endif + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; +#ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +#endif + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +#ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +#else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +#endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; +#ifdef USE_NEW_DYNAREC + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } +#else + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } +#endif + } +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +#else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +#endif + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +#ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +#else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +#endif + } + } + +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) +#else + if (valid_block && block->was_recompiled) +#endif + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +#ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +#endif + + inrecomp=1; + code(); + inrecomp=0; + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cs+cpu_state.pc; +#ifdef USE_NEW_DYNAREC + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } +#ifdef USE_NEW_DYNAREC + else + cpu_state.oldpc = cpu_state.pc; +#endif + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { +#ifdef USE_NEW_DYNAREC + trap = 0; +#endif + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_common/386_dynarec.c b/src/cpu_common/386_dynarec.c new file mode 100644 index 000000000..b03f723c1 --- /dev/null +++ b/src/cpu_common/386_dynarec.c @@ -0,0 +1,1007 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; +#endif + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); +#ifdef USE_NEW_DYNAREC + codeblock_t *block = &codeblock[codeblock_hash[hash]]; +#else + codeblock_t *block = codeblock_hash[hash]; +#endif + int valid_block = 0; +#ifdef USE_NEW_DYNAREC + + if (!cpu_state.abrt) +#else + trap = 0; + + if (block && !cpu_state.abrt) +#endif + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); +#ifdef USE_NEW_DYNAREC + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +#else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +#endif + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; +#ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +#endif + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +#ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +#else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +#endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { +#ifdef USE_NEW_DYNAREC + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +#else + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +#endif + } + } +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +#else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +#endif + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +#ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +#else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +#endif + } + } + +#ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) +#else + if (valid_block && block->was_recompiled) +#endif + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +#ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +#endif + + inrecomp=1; + code(); + inrecomp=0; + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ +#ifdef USE_NEW_DYNAREC + start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +#else + start_pc = cpu_state.pc; +#endif + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { +#ifndef USE_NEW_DYNAREC + oldcs=CS; + oldcpl = CPL; +#endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + +#ifndef USE_NEW_DYNAREC + if (!use32) cpu_state.pc &= 0xffff; +#endif + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +#ifdef USE_NEW_DYNAREC + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) +#else + if ((cpu_state.pc - start_pc) > 1000) +#endif + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } +#ifdef USE_NEW_DYNAREC + else + cpu_state.oldpc = cpu_state.pc; +#endif + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +#ifndef USE_NEW_DYNAREC + CS = oldcs; +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +#endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { +#ifdef USE_NEW_DYNAREC + trap = 0; +#endif + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + } + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu_common/386_dynarec.c.temp b/src/cpu_common/386_dynarec.c.temp new file mode 100644 index 000000000..78130f3c0 --- /dev/null +++ b/src/cpu_common/386_dynarec.c.temp @@ -0,0 +1,900 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif + +#define HAVE_STDARG_H +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#ifdef USE_DYNAREC +#include "codegen.h" +#ifdef USE_NEW_DYNAREC +#include "codegen_backend.h" +#endif +#endif +#include "386_common.h" + + +#define CPU_BLOCK_END() cpu_block_end = 1 + + +int inrecomp = 0, cpu_block_end = 0; +int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; +int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; + + +#ifdef ENABLE_386_DYNAREC_LOG +int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; + + +void +x386_dynarec_log(const char *fmt, ...) +{ + va_list ap; + + if (x386_dynarec_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define x386_dynarec_log(fmt, ...) +#endif + + +static __inline void fetch_ea_32_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +static __inline void fetch_ea_16_long(uint32_t rmdat) +{ + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) + { + uint32_t addr = easeg + cpu_state.eaaddr; + if ( readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } + cpu_state.last_ea = cpu_state.eaaddr; +} + +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 + +#include "x86_flags.h" + + +/*Prefetch emulation is a fairly simplistic model: + - All instruction bytes must be fetched before it starts. + - Cycles used for non-instruction memory accesses are counted and subtracted + from the total cycles taken + - Any remaining cycles are used to refill the prefetch queue. + + Note that this is only used for 286 / 386 systems. It is disabled when the + internal cache on 486+ CPUs is enabled. +*/ +static int prefetch_bytes = 0; +static int prefetch_prefixes = 0; + +static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +{ + int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; + + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) + { + if (ea32) + { + if ((modrm & 7) == 4) + { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } + else + { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } + else + { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } + + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) + { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } + + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; + + while (instr_cycles >= cpu_prefetch_cycles) + { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } + + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; +} + +static void prefetch_flush() +{ + prefetch_bytes = 0; +} + +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) + +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_FLUSH() prefetch_flush() + + +void enter_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + uint32_t old_cr0 = cr0; + uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16); + + cr0 &= ~0x8000000d; + cpu_state.flags = 2; + cpu_state.eflags = 0; + + in_smm = 1; + mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + smi_latched = 1; + + mem_writel_phys(smram_state + 0xf8, smbase); + mem_writel_phys(smram_state + 0x128, cr4); + mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit); + mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base); + mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access); + mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit); + mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base); + mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access); + mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit); + mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base); + mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access); + mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit); + mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base); + mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access); + mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit); + mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base); + mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access); + mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit); + mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base); + mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access); + mem_writel_phys(smram_state + 0x178, ldt.limit); + mem_writel_phys(smram_state + 0x17c, ldt.base); + mem_writel_phys(smram_state + 0x180, ldt.access); + mem_writel_phys(smram_state + 0x184, gdt.limit); + mem_writel_phys(smram_state + 0x188, gdt.base); + mem_writel_phys(smram_state + 0x18c, gdt.access); + mem_writel_phys(smram_state + 0x190, idt.limit); + mem_writel_phys(smram_state + 0x194, idt.base); + mem_writel_phys(smram_state + 0x198, idt.access); + mem_writel_phys(smram_state + 0x19c, tr.limit); + mem_writel_phys(smram_state + 0x1a0, tr.base); + mem_writel_phys(smram_state + 0x1a4, tr.access); + + mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg); + mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg); + mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg); + mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg); + mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg); + mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg); + mem_writel_phys(smram_state + 0x1c0, ldt.seg); + mem_writel_phys(smram_state + 0x1c4, tr.seg); + + mem_writel_phys(smram_state + 0x1c8, dr[7]); + mem_writel_phys(smram_state + 0x1cc, dr[6]); + mem_writel_phys(smram_state + 0x1d0, EAX); + mem_writel_phys(smram_state + 0x1d4, ECX); + mem_writel_phys(smram_state + 0x1d8, EDX); + mem_writel_phys(smram_state + 0x1dc, EBX); + mem_writel_phys(smram_state + 0x1e0, ESP); + mem_writel_phys(smram_state + 0x1e4, EBP); + mem_writel_phys(smram_state + 0x1e8, ESI); + mem_writel_phys(smram_state + 0x1ec, EDI); + mem_writel_phys(smram_state + 0x1f0, cpu_state.pc); + mem_writel_phys(smram_state + 0x1d0, old_flags); + mem_writel_phys(smram_state + 0x1f8, cr3); + mem_writel_phys(smram_state + 0x1fc, old_cr0); + + ds = es = fs_seg = gs = ss = 0; + + DS = ES = FS = GS = SS = 0; + + cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit + = cpu_state.seg_ss.limit = 0xffffffff; + + cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high + = cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff; + + cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low + = cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0; + + cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access + = cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked + = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + + CS = 0x3000; + cs = smbase; + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.checked = 1; + + cr4 = 0; + dr[7] = 0x400; + cpu_state.pc = 0x8000; + + nmi_mask = 0; +} + +void leave_smm() +{ + uint32_t smram_state = smbase + 0xfe00; + + smbase = mem_readl_phys(smram_state + 0xf8); + cr4 = mem_readl_phys(smram_state + 0x128); + + cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130); + cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134); + cpu_state.seg_es.limit_low = cpu_state.seg_es.base; + cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138); + + cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c); + cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140); + cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base; + cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144); + + cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148); + cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c); + cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base; + cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150); + + cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154); + cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158); + cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base; + cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c); + + cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160); + cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164); + cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base; + cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168); + + cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c); + cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170); + cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base; + cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174); + + ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178); + ldt.base = mem_readl_phys(smram_state + 0x17c); + ldt.limit_low = ldt.base; + ldt.access = mem_readl_phys(smram_state + 0x180); + + gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184); + gdt.base = mem_readl_phys(smram_state + 0x188); + gdt.limit_low = gdt.base; + gdt.access = mem_readl_phys(smram_state + 0x18c); + + idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190); + idt.base = mem_readl_phys(smram_state + 0x194); + idt.limit_low = idt.base; + idt.access = mem_readl_phys(smram_state + 0x198); + + tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c); + tr.base = mem_readl_phys(smram_state + 0x1a0); + tr.limit_low = tr.base; + tr.access = mem_readl_phys(smram_state + 0x1a4); + + ES = mem_readl_phys(smram_state + 0x1a8); + CS = mem_readl_phys(smram_state + 0x1ac); + SS = mem_readl_phys(smram_state + 0x1b0); + DS = mem_readl_phys(smram_state + 0x1b4); + FS = mem_readl_phys(smram_state + 0x1b8); + GS = mem_readl_phys(smram_state + 0x1bc); + ldt.seg = mem_readl_phys(smram_state + 0x1c0); + tr.seg = mem_readl_phys(smram_state + 0x1c4); + + dr[7] = mem_readl_phys(smram_state + 0x1c8); + dr[6] = mem_readl_phys(smram_state + 0x1cc); + EAX = mem_readl_phys(smram_state + 0x1d0); + ECX = mem_readl_phys(smram_state + 0x1d4); + EDX = mem_readl_phys(smram_state + 0x1d8); + EBX = mem_readl_phys(smram_state + 0x1dc); + ESP = mem_readl_phys(smram_state + 0x1e0); + EBP = mem_readl_phys(smram_state + 0x1e4); + ESI = mem_readl_phys(smram_state + 0x1e8); + EDI = mem_readl_phys(smram_state + 0x1ec); + + cpu_state.pc = mem_readl_phys(smram_state + 0x1f0); + uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4); + cpu_state.flags = new_flags & 0xffff; + cpu_state.eflags = new_flags >> 16; + cr3 = mem_readl_phys(smram_state + 0x1f8); + cr0 = mem_readl_phys(smram_state + 0x1fc); + + cpu_state.seg_cs.access &= ~0x60; + cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss + + if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG)) + { + cpu_state.seg_cs.checked = CS ? 1 : 0; + cpu_state.seg_ds.checked = DS ? 1 : 0; + cpu_state.seg_es.checked = ES ? 1 : 0; + cpu_state.seg_fs.checked = FS ? 1 : 0; + cpu_state.seg_gs.checked = GS ? 1 : 0; + cpu_state.seg_ss.checked = SS ? 1 : 0; + } + else + { + cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked + = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1; + } + + mem_restore_mem_state(smbase, 131072); + in_smm = 0; + + nmi_mask = 1; +} + +#define OP_TABLE(name) ops_ ## name +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#include "386_ops.h" + + +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) + +#ifdef USE_DYNAREC +static int cycles_main = 0; + + +void exec386_dynarec(int cycs) +{ + int vector; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; + uint32_t start_pc = 0; + + int cyc_period = cycs / 2000; /*5us*/ + + cycles_main += cycs; + while (cycles_main > 0) + { + int cycles_start; + + cycles += cyc_period; + cycles_start = cycles; + + while (cycles>0) + { + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; + + cycdiff=0; + oldcyc=cycles; + if (!CACHE_ON()) /*Interpret block*/ + { + cpu_block_end = 0; + x86_was_reset = 0; + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } + + if (!use32) cpu_state.pc &= 0xffff; + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + ins++; + } + } + else + { + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = codeblock_hash[hash]; + int valid_block = 0; + trap = 0; + + if (block && !cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage*/ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && + (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) + { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && + (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + block = new_block; + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); + page_t *page_2 = &pages[phys_addr_2 >> 12]; + + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; + } + } + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; + } + } + + if (valid_block && block->was_recompiled) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + + codeblock_hash[hash] = block; + + inrecomp=1; + code(); + inrecomp=0; + if (!use32) cpu_state.pc &= 0xffff; + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + codegen_block_start_recompile(block); + codegen_in_recompile = 1; + + while (!cpu_block_end) + { + oldcs = CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + codegen_block_init(phys_addr); + + while (!cpu_block_end) + { + oldcs=CS; + oldcpl = CPL; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; + + cpu_state.pc++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + if (!use32) cpu_state.pc &= 0xffff; + + /*Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ + if ((cpu_state.pc - start_pc) > 1000) + CPU_BLOCK_END(); + + if (in_smm && smi_line && is_pentium) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) + { + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + CS = oldcs; +#ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Double fault %i\n", ins); +#endif + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + #ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); + #endif + } + } + } + + if (in_smm && smi_line && is_pentium) + { + enter_smm(); + } + + else if (trap) + { + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags&I_FLAG) && pic_intpending) + { + vector = picinterrupt(); + if (vector != -1) + { + CPU_BLOCK_END(); + flags_rebuild(); + if (msw&1) + { + pmodeint(vector,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=vector<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } + } + + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + + cycles_main -= (cycles_start - cycles); + } +} +#endif diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu_common/386_dynarec_ops.c similarity index 90% rename from src/cpu/386_dynarec_ops.c rename to src/cpu_common/386_dynarec_ops.c index 7585a305b..42edfbef5 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu_common/386_dynarec_ops.c @@ -7,18 +7,19 @@ #ifndef INFINITY # define INFINITY (__builtin_inff()) #endif -#include "../86box.h" + +#include "86box.h" #include "cpu.h" -#include "../timer.h" +#include "timer.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" #include "x86_flags.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" #include "codegen.h" -#include "../pic.h" #define CPU_BLOCK_END() cpu_block_end = 1 @@ -55,8 +56,8 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) cpu_state.last_ea = cpu_state.eaaddr; } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); +#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) @@ -64,6 +65,8 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) #define PREFETCH_FLUSH() #define OP_TABLE(name) dynarec_ops_ ## name + #define CLOCK_CYCLES(c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + #include "386_ops.h" diff --git a/src/cpu_new/386_ops.h b/src/cpu_common/386_ops.h similarity index 99% rename from src/cpu_new/386_ops.h rename to src/cpu_common/386_ops.h index b3d331423..04ea68150 100644 --- a/src/cpu_new/386_ops.h +++ b/src/cpu_common/386_ops.h @@ -167,12 +167,14 @@ static int ILLEGAL(uint32_t fetchdat) return 0; } +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686))) static int internal_illegal(char *s) { cpu_state.pc = cpu_state.oldpc; x86gpf(s, 0); return cpu_state.abrt; } +#endif #ifdef ENABLE_386_DYNAREC_LOG extern void x386_dynarec_log(const char *fmt, ...); @@ -183,13 +185,11 @@ extern void x386_dynarec_log(const char *fmt, ...); #endif #include "x86seg.h" -# include "x86_ops_amd.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" -#include "x86_ops_call.h" #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -202,7 +202,6 @@ extern void x386_dynarec_log(const char *fmt, ...); # include "x86_ops_i686.h" #endif #include "x86_ops_mmx.h" -#include "x86_ops_3dnow.h" #include "x86_ops_mmx_arith.h" #include "x86_ops_mmx_cmp.h" #include "x86_ops_mmx_logic.h" @@ -220,10 +219,15 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_rep.h" #include "x86_ops_ret.h" #include "x86_ops_set.h" -#include "x86_ops_shift.h" #include "x86_ops_stack.h" #include "x86_ops_string.h" #include "x86_ops_xchg.h" +#include "x86_ops_call.h" +#include "x86_ops_shift.h" +#ifdef USE_NEW_DYNAREC +#include "x86_ops_amd.h" +#include "x86_ops_3dnow.h" +#endif static int op0F_w_a16(uint32_t fetchdat) @@ -632,6 +636,7 @@ const OpFn OP_TABLE(winchip_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#ifdef USE_NEW_DYNAREC const OpFn OP_TABLE(winchip2_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -722,6 +727,7 @@ const OpFn OP_TABLE(winchip2_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#endif const OpFn OP_TABLE(pentium_0f)[1024] = { @@ -905,6 +911,7 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#ifdef USE_NEW_DYNAREC const OpFn OP_TABLE(k6_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1086,7 +1093,9 @@ const OpFn OP_TABLE(k62_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1177,6 +1186,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; +#endif #ifdef DEV_BRANCH #ifdef USE_I686 @@ -1271,7 +1281,6 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -#if 0 const OpFn OP_TABLE(pentium2_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1362,7 +1371,6 @@ const OpFn OP_TABLE(pentium2_0f)[1024] = /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -#endif const OpFn OP_TABLE(pentium2d_0f)[1024] = { diff --git a/src/cpu/808x.c b/src/cpu_common/808x.c similarity index 98% rename from src/cpu/808x.c rename to src/cpu_common/808x.c index 929d08bb6..ede1412cd 100644 --- a/src/cpu/808x.c +++ b/src/cpu_common/808x.c @@ -23,17 +23,18 @@ #include #include #include + #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../nmi.h" -#include "../pic.h" -#include "../timer.h" +#include "machine.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "nmi.h" +#include "pic.h" +#include "timer.h" /* The opcode of the instruction currently being executed. */ uint8_t opcode; @@ -58,7 +59,6 @@ int is8086 = 0; /* Variables for handling the non-maskable interrupts. */ int nmi = 0, nmi_auto_clear = 0; -int nmi_enable = 1; /* Was the CPU ever reset? */ int x86_was_reset = 0; @@ -653,6 +653,13 @@ sign_extend(uint8_t data) } +static uint32_t +sign_extend32(uint16_t data) +{ + return data + (data < 0x8000 ? 0 : 0xffff0000); +} + + /* Fetches the effective address from the prefetch queue according to MOD and R/M. */ static void do_mod_rm(void) @@ -937,7 +944,6 @@ reset_common(int hard) cpu_state.flags = 2; trap = 0; ovr_seg = NULL; - in_lock = 0; EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; @@ -946,6 +952,7 @@ reset_common(int hard) resetreadlookup(); makemod1table(); resetmcr(); + pfq_clear(); cpu_set_edx(); mmu_perm = 4; pfq_size = (is8086) ? 6 : 4; @@ -960,12 +967,12 @@ reset_common(int hard) x86_was_reset = 1; cpu_alt_reset = 0; - pfq_clear(); prefetching = 1; - takeint = 0; cpu_ven_reset(); + + cpu_alu_op = 0; } @@ -1761,6 +1768,7 @@ execx86(int cycs) uint8_t temp = 0, temp2; uint16_t addr, tempw; uint16_t new_cs, new_ip; + uint32_t result; int bits; cycles += cycs; @@ -2743,17 +2751,25 @@ execx86(int cycs) case 0x28: /* IMUL */ wait(1, 0); if (opcode & 1) { + result = cpu_data; mul(AX, cpu_data); AX = cpu_data; DX = cpu_dest; cpu_data |= DX; - set_co_mul(DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + result = ((uint32_t) DX << 16) | AX; + if ((rmdat & 0x38) == 0x20) + set_co_mul(DX != 0x0000); + else + set_co_mul(result != sign_extend32(AX)); } else { mul(AL, cpu_data); AL = (uint8_t) cpu_data; AH = (uint8_t) cpu_dest; cpu_data |= AH; - set_co_mul(AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + if ((rmdat & 0x38) == 0x20) + set_co_mul(AH != 0x00); + else + set_co_mul(AX != sign_extend(AL)); } /* NOTE: When implementing the V20, care should be taken to not change the zero flag. */ @@ -2888,6 +2904,8 @@ execx86(int cycs) if (noint) noint = 0; + + cpu_alu_op = 0; } ins++; diff --git a/src/cpu_common/codegen_public.h b/src/cpu_common/codegen_public.h new file mode 100644 index 000000000..e5ca4b33e --- /dev/null +++ b/src/cpu_common/codegen_public.h @@ -0,0 +1,64 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen_public.h 1.0.0 2020/01/27 + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef _CODEGEN_PUBLIC_H_ +#define _CODEGEN_PUBLIC_H_ + +#ifndef USE_NEW_DYNAREC +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 +#define PAGE_MASK_SHIFT 4 +#else +#define PAGE_MASK_SHIFT 6 +#endif +#define PAGE_MASK_MASK 63 + +#ifdef USE_NEW_DYNAREC +#define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_INVALID 0 +#endif + + +extern void codegen_init(); +#ifdef USE_NEW_DYNAREC +extern void codegen_close(); +#endif +extern void codegen_flush(); + + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +extern uint32_t recomp_page; +extern int codegen_in_recompile; + +#endif diff --git a/src/cpu/cpu.c b/src/cpu_common/cpu.c similarity index 70% rename from src/cpu/cpu.c rename to src/cpu_common/cpu.c index 599c90e6e..84692d702 100644 --- a/src/cpu/cpu.c +++ b/src/cpu_common/cpu.c @@ -38,29 +38,28 @@ * Boston, MA 02111-1307 * USA. */ +#include #include #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../io.h" +#include "device.h" +#include "machine.h" +#include "86box_io.h" #include "x86_ops.h" -#include "../mem.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pci.h" +#include "mem.h" +#include "nmi.h" +#include "pic.h" +#include "pci.h" #ifdef USE_DYNAREC # include "codegen.h" #endif -#if 1 static void cpu_write(uint16_t addr, uint8_t val, void *priv); static uint8_t cpu_read(uint16_t addr, void *priv); -#endif enum { @@ -77,6 +76,14 @@ enum { CPUID_FXSR = (1 << 24) }; +#ifdef USE_NEW_DYNAREC +/*Addition flags returned by CPUID function 0x80000001*/ +enum +{ + CPUID_3DNOW = (1 << 31) +}; +#endif + #ifdef USE_DYNAREC const OpFn *x86_dynarec_opcodes; @@ -99,6 +106,9 @@ const OpFn *x86_dynarec_opcodes_df_a16; const OpFn *x86_dynarec_opcodes_df_a32; const OpFn *x86_dynarec_opcodes_REPE; const OpFn *x86_dynarec_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC +const OpFn *x86_dynarec_opcodes_3DNOW; +#endif #endif const OpFn *x86_opcodes; @@ -121,6 +131,9 @@ const OpFn *x86_opcodes_df_a16; const OpFn *x86_opcodes_df_a32; const OpFn *x86_opcodes_REPE; const OpFn *x86_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC +const OpFn *x86_opcodes_3DNOW; +#endif int in_smm = 0, smi_line = 0, smi_latched = 0; uint32_t smbase = 0x30000; @@ -128,6 +141,7 @@ uint32_t smbase = 0x30000; CPU *cpu_s; int cpu_effective; int cpu_multi; +double cpu_dmulti; int cpu_16bitbus; int cpu_busspeed; int cpu_cyrix_alignment; @@ -146,7 +160,8 @@ uint32_t cpu_features; int is286, is386, - is486, + is486 = 1, + is486sx, is486dx, is486sx2, is486dx2, isdx4, cpu_iscyrix, isibmcpu, israpidcad, @@ -189,10 +204,21 @@ uint64_t ecx1e0_msr = 0; uint64_t ecx570_msr = 0; #endif -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */ +#ifdef USE_NEW_DYNAREC +uint64_t star = 0; /* AMD K6-2+. */ +#endif + +#ifdef USE_NEW_DYNAREC +uint64_t amd_efer = 0, amd_whcr = 0, + amd_uwccr = 0, amd_epmr = 0, /* AMD K6-2+ registers. */ + amd_psor = 0, amd_pfir = 0, + amd_l2aar = 0; +#else uint64_t amd_efer = 0, amd_whcr = 0; #endif +#endif int timing_rr; int timing_mr, timing_mrl; @@ -254,27 +280,34 @@ cpu_set(void) cpu_alt_reset = 0; - CPUID = cpu_s->cpuid_model; - is8086 = (cpu_s->cpu_type > CPU_8088); - is286 = (cpu_s->cpu_type >= CPU_286); - is386 = (cpu_s->cpu_type >= CPU_386SX); - isibmcpu = (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); - israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); - is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); - hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); + CPUID = cpu_s->cpuid_model; + is8086 = (cpu_s->cpu_type > CPU_8088); + is286 = (cpu_s->cpu_type >= CPU_286); + is386 = (cpu_s->cpu_type >= CPU_386SX); + isibmcpu = (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL ); + is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2); + is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX); + is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2); + is486dx2 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); + isdx4 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4); + is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP); + hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); #else - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86); + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86); #endif cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); - if (cpu_s->multi) { - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; - } - cpu_multi = cpu_s->multi; + if (cpu_s->multi) + cpu_busspeed = cpu_s->rspeed / cpu_s->multi; + else + cpu_busspeed = cpu_s->rspeed; + cpu_multi = (int) ceil(cpu_s->multi); + cpu_dmulti = cpu_s->multi; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; if ((cpu_s->cpu_type == CPU_8088) || (cpu_s->cpu_type == CPU_8086) || @@ -292,16 +325,15 @@ cpu_set(void) else cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; - if (cpu_s->pci_speed) - { - pci_nonburst_time = 4*cpu_s->rspeed / cpu_s->pci_speed; - pci_burst_time = cpu_s->rspeed / cpu_s->pci_speed; - } - else - { - pci_nonburst_time = 4; - pci_burst_time = 1; - } + if (cpu_busspeed < 42500000) + cpu_pci_speed = cpu_busspeed; + else if ((cpu_busspeed > 42500000) && (cpu_busspeed < 84000000)) + cpu_pci_speed = cpu_busspeed / 2; + else + cpu_pci_speed = cpu_busspeed / 3; + + pci_burst_time = cpu_s->rspeed / cpu_pci_speed; + pci_nonburst_time = 4 * pci_burst_time; if (cpu_iscyrix) io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL); @@ -320,9 +352,15 @@ cpu_set(void) #endif x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; +#ifdef USE_NEW_DYNAREC + x86_opcodes_3DNOW = ops_3DNOW; +#endif #ifdef USE_DYNAREC x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; +#ifdef USE_NEW_DYNAREC + x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; +#endif #endif #ifdef USE_DYNAREC @@ -622,8 +660,13 @@ cpu_set(void) timing_jmp_pm_gate = 32; timing_misaligned = 3; break; - + case CPU_RAPIDCAD: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); +#else + x86_setopcodes(ops_386, ops_486_0f); +#endif timing_rr = 1; /*register dest - register src*/ timing_rm = 2; /*register dest - memory src*/ timing_mr = 3; /*memory dest - register src*/ @@ -652,6 +695,7 @@ cpu_set(void) timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_486SLC: @@ -735,7 +779,9 @@ cpu_set(void) cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; /*FALLTHROUGH*/ case CPU_i486SX: + case CPU_i486SX2: case CPU_i486DX: + case CPU_i486DX2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else @@ -773,7 +819,11 @@ cpu_set(void) break; case CPU_Am486SX: + case CPU_Am486SX2: case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: /*AMD timing identical to Intel*/ #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); @@ -813,6 +863,7 @@ cpu_set(void) case CPU_Cx486S: case CPU_Cx486DX: + case CPU_Cx486DX2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else @@ -931,6 +982,50 @@ cpu_set(void) cpu_cyrix_alignment = 1; break; +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); +#else + x86_setopcodes(ops_386, ops_winchip2_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 2; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 2; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; + codegen_timing_set(&codegen_timing_winchip2); + break; +#endif + case CPU_PENTIUM: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1017,7 +1112,7 @@ cpu_set(void) #endif break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); @@ -1188,7 +1283,7 @@ cpu_set(void) break; #endif -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: #ifdef USE_DYNAREC @@ -1205,10 +1300,32 @@ cpu_set(void) timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; +#if defined(USE_NEW_DYNAREC) && defined(USE_DYNAREC) + codegen_timing_set(&codegen_timing_k6); +#endif break; case CPU_K6: @@ -1226,13 +1343,83 @@ cpu_set(void) timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_pentium); #endif +#endif + break; +#endif + +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); +#else + x86_setopcodes(ops_386, ops_k62_0f); +#endif + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + codegen_timing_set(&codegen_timing_k6); break; #endif @@ -1256,24 +1443,46 @@ cpu_set(void) x86_opcodes_df_a16 = ops_fpu_686_df_a16; x86_opcodes_df_a32 = ops_fpu_686_df_a32; timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 1; /*memory dest - register src*/ - timing_mm = 1; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 1; /*memory dest - register src long*/ - timing_mml = 1; + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_686); +#endif #endif break; -#if 0 case CPU_PENTIUM2: #ifdef USE_DYNAREC x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); @@ -1293,23 +1502,45 @@ cpu_set(void) x86_opcodes_df_a16 = ops_fpu_686_df_a16; x86_opcodes_df_a32 = ops_fpu_686_df_a32; timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 1; /*memory dest - register src*/ - timing_mm = 1; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 1; /*memory dest - register src long*/ - timing_mml = 1; + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_686); #endif - break; #endif + break; case CPU_PENTIUM2D: #ifdef USE_DYNAREC @@ -1330,20 +1561,43 @@ cpu_set(void) x86_opcodes_df_a16 = ops_fpu_686_df_a16; x86_opcodes_df_a32 = ops_fpu_686_df_a32; timing_rr = 1; /*register dest - register src*/ - timing_rm = 1; /*register dest - memory src*/ - timing_mr = 1; /*memory dest - register src*/ - timing_mm = 1; - timing_rml = 1; /*register dest - memory src long*/ - timing_mrl = 1; /*memory dest - register src long*/ - timing_mml = 1; + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; timing_misaligned = 3; cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR; #ifdef USE_DYNAREC +#ifdef USE_NEW_DYNAREC + codegen_timing_set(&codegen_timing_k6); +#else codegen_timing_set(&codegen_timing_686); +#endif #endif break; #endif @@ -1373,7 +1627,9 @@ cpu_CPUID(void) { switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { + case CPU_RAPIDCAD: case CPU_i486DX: + case CPU_i486DX2: if (!EAX) { EAX = 0x00000001; @@ -1410,6 +1666,7 @@ cpu_CPUID(void) break; case CPU_Am486SX: + case CPU_Am486SX2: if (!EAX) { EAX = 1; @@ -1427,6 +1684,9 @@ cpu_CPUID(void) break; case CPU_Am486DX: + case CPU_Am486DX2: + case CPU_Am486DX4: + case CPU_Am5x86: if (!EAX) { EAX = 1; @@ -1475,6 +1735,68 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: + switch (EAX) + { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) + { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } + else + { + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = 0x580; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = 0x580; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x20544449; /*IDT WinChip 2-3D*/ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; +#endif + case CPU_PENTIUM: if (!EAX) { @@ -1493,7 +1815,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: if (!EAX) { @@ -1576,7 +1898,7 @@ cpu_CPUID(void) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; } else if (EAX == 0x80000000) { @@ -1587,7 +1909,7 @@ cpu_CPUID(void) { EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; } else if (EAX == 0x80000002) { @@ -1627,6 +1949,169 @@ cpu_CPUID(void) break; #endif +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + case CPU_K6_2C: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x7365636f; /*ocessor*/ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_3: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + ECX = 0x01004220; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; + + case 0x80000007: /*PowerNow information*/ + EDX = 7; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; +#endif + case CPU_PENTIUMMMX: if (!EAX) { @@ -1646,7 +2131,7 @@ cpu_CPUID(void) break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: if (!EAX) { @@ -1747,7 +2232,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; - /* case CPU_PENTIUM2: + case CPU_PENTIUM2: if (!EAX) { EAX = 0x00000002; @@ -1769,7 +2254,7 @@ cpu_CPUID(void) } else EAX = EBX = ECX = EDX = 0; - break; */ + break; case CPU_PENTIUM2D: if (!EAX) @@ -1802,7 +2287,7 @@ cpu_CPUID(void) void cpu_ven_reset(void) { -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_K5: @@ -1810,6 +2295,34 @@ void cpu_ven_reset(void) case CPU_K6: amd_efer = amd_whcr = 0ULL; break; + case CPU_K6_2: + amd_efer = amd_whcr = 0ULL; + star = 0ULL; + break; +#ifdef USE_NEW_DYNAREC + case CPU_K6_2C: + amd_efer = 2ULL; + amd_whcr = star = 0ULL; + amd_psor = 0x018cULL; + amd_uwccr = 0ULL; + break; + case CPU_K6_3: + amd_efer = 2ULL; + amd_whcr = star = 0ULL; + amd_psor = 0x008cULL; + amd_uwccr = 0ULL; + amd_pfir = amd_l2aar = 0ULL; + break; + case CPU_K6_2P: + case CPU_K6_3P: + amd_efer = 2ULL; + amd_whcr = star = 0ULL; + amd_psor = 0x008cULL; + amd_uwccr = 0ULL; + amd_pfir = amd_l2aar = 0ULL; + amd_epmr = 0ULL; + break; +#endif } #endif } @@ -1819,6 +2332,9 @@ void cpu_RDMSR() switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: +#endif EAX = EDX = 0; switch (ECX) { @@ -1848,7 +2364,7 @@ void cpu_RDMSR() } break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -1881,6 +2397,189 @@ void cpu_RDMSR() break; #endif +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2C: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + case 0xC0000085: + EAX = amd_uwccr & 0xffffffff; + EDX = amd_uwccr >> 32; + break; + case 0xC0000087: + EAX = amd_psor & 0xffffffff; + EDX = amd_psor >> 32; + break; + case 0xC0000088: + EAX = amd_pfir & 0xffffffff; + EDX = amd_pfir >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_3: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + case 0xC0000085: + EAX = amd_uwccr & 0xffffffff; + EDX = amd_uwccr >> 32; + break; + case 0xC0000087: + EAX = amd_psor & 0xffffffff; + EDX = amd_psor >> 32; + break; + case 0xC0000088: + EAX = amd_pfir & 0xffffffff; + EDX = amd_pfir >> 32; + break; + case 0xC0000089: + EAX = amd_l2aar & 0xffffffff; + EDX = amd_l2aar >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) + { + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = ecx83_msr & 0xffffffff; + EDX = ecx83_msr >> 32; + break; + case 0xC0000080: + EAX = amd_efer & 0xffffffff; + EDX = amd_efer >> 32; + break; + case 0xC0000081: + EAX = star & 0xffffffff; + EDX = star >> 32; + break; + case 0xC0000082: + EAX = amd_whcr & 0xffffffff; + EDX = amd_whcr >> 32; + break; + case 0xC0000085: + EAX = amd_uwccr & 0xffffffff; + EDX = amd_uwccr >> 32; + break; + case 0xC0000086: + EAX = amd_epmr & 0xffffffff; + EDX = amd_epmr >> 32; + break; + case 0xC0000087: + EAX = amd_psor & 0xffffffff; + EDX = amd_psor >> 32; + break; + case 0xC0000088: + EAX = amd_pfir & 0xffffffff; + EDX = amd_pfir >> 32; + break; + case 0xC0000089: + EAX = amd_l2aar & 0xffffffff; + EDX = amd_l2aar >> 32; + break; + default: + x86gpf(NULL, 0); + break; + } + break; +#endif + case CPU_PENTIUM: case CPU_PENTIUMMMX: EAX = EDX = 0; @@ -1892,7 +2591,7 @@ void cpu_RDMSR() break; } break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -1910,6 +2609,7 @@ void cpu_RDMSR() #ifdef DEV_BRANCH #ifdef USE_I686 case CPU_PENTIUMPRO: + case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; switch (ECX) @@ -2027,7 +2727,7 @@ void cpu_RDMSR() break; default: i686_invalid_rdmsr: - pclog("Invalid MSR read %08X\n", ECX); + // pclog("RDMSR: Invalid MSR: %08X\n", ECX); x86gpf(NULL, 0); break; } @@ -2039,13 +2739,16 @@ i686_invalid_rdmsr: void cpu_WRMSR() { -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) uint64_t temp; #endif switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type) { case CPU_WINCHIP: +#ifdef USE_NEW_DYNAREC + case CPU_WINCHIP2: +#endif switch (ECX) { case 0x02: @@ -2066,10 +2769,16 @@ void cpu_WRMSR() cpu_features |= CPU_FEATURE_MMX; else cpu_features &= ~CPU_FEATURE_MMX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; +#ifdef USE_NEW_DYNAREC + if ((EAX & (1 << 20)) && machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + else + cpu_features &= ~CPU_FEATURE_3DNOW; +#endif if (EAX & (1 << 29)) CPUID = 0; else @@ -2084,7 +2793,7 @@ void cpu_WRMSR() } break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) case CPU_K5: case CPU_5K86: case CPU_K6: @@ -2116,6 +2825,169 @@ void cpu_WRMSR() break; #endif +#ifdef USE_NEW_DYNAREC + case CPU_K6_2: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~1ULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2C: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~0xfULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000085: + amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000087: + amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000088: + amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_3: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~0x1fULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000085: + amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000087: + amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000088: + amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000089: + amd_l2aar = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) + { + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + case 0x83: + ecx83_msr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000080: + temp = EAX | ((uint64_t)EDX << 32); + if (temp & ~0x1fULL) + x86gpf(NULL, 0); + else + amd_efer = temp; + break; + case 0xC0000081: + star = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000082: + amd_whcr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000085: + amd_uwccr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000086: + amd_epmr = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000087: + amd_psor = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000088: + amd_pfir = EAX | ((uint64_t)EDX << 32); + break; + case 0xC0000089: + amd_l2aar = EAX | ((uint64_t)EDX << 32); + break; + default: + x86gpf(NULL, 0); + break; + } + break; +#endif + case CPU_PENTIUM: case CPU_PENTIUMMMX: switch (ECX) @@ -2125,7 +2997,7 @@ void cpu_WRMSR() break; } break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -2142,6 +3014,7 @@ void cpu_WRMSR() #ifdef DEV_BRANCH #ifdef USE_I686 case CPU_PENTIUMPRO: + case CPU_PENTIUM2: case CPU_PENTIUM2D: switch (ECX) { @@ -2227,7 +3100,7 @@ void cpu_WRMSR() break; default: i686_invalid_wrmsr: - pclog("Invalid MSR write %08X: %08X%08X\n", ECX, EDX, EAX); + // pclog("WRMSR: Invalid MSR: %08X\n", ECX); x86gpf(NULL, 0); break; } @@ -2271,7 +3144,7 @@ static void cpu_write(uint16_t addr, uint8_t val, void *priv) if ((ccr3 & 0xf0) == 0x10) { ccr4 = val; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86) { if (val & 0x80) diff --git a/src/cpu_new/cpu.h b/src/cpu_common/cpu.h similarity index 75% rename from src/cpu_new/cpu.h rename to src/cpu_common/cpu.h index 185250319..4cc156e6a 100644 --- a/src/cpu_new/cpu.h +++ b/src/cpu_common/cpu.h @@ -20,50 +20,76 @@ */ #ifndef EMU_CPU_H # define EMU_CPU_H +enum { + CPU_8088, /* 808x class CPUs */ + CPU_8086, +#ifdef USE_NEC_808X + CPU_V20, /* NEC 808x class CPUs - future proofing */ + CPU_V30, +#endif + CPU_286, /* 286 class CPUs */ + CPU_386SX, /* 386 class CPUs */ + CPU_386DX, + CPU_IBM386SLC, + CPU_IBM486SLC, + CPU_IBM486BL, + CPU_RAPIDCAD, + CPU_486SLC, + CPU_486DLC, + CPU_i486SX, /* 486 class CPUs */ + CPU_Am486SX, + CPU_Cx486S, + CPU_i486SX2, + CPU_Am486SX2, + CPU_i486DX, + CPU_i486DX2, + CPU_Am486DX, + CPU_Am486DX2, + CPU_Cx486DX, + CPU_Cx486DX2, + CPU_iDX4, + CPU_Am486DX4, + CPU_Cx486DX4, + CPU_Am5x86, + CPU_Cx5x86, + CPU_WINCHIP, /* 586 class CPUs */ +#ifdef USE_NEW_DYNAREC + CPU_WINCHIP2, +#endif + CPU_PENTIUM, + CPU_PENTIUMMMX, +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) + CPU_Cx6x86, + CPU_Cx6x86MX, + CPU_Cx6x86L, + CPU_CxGX1, +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) + CPU_K5, + CPU_5K86, + CPU_K6, +#endif +#ifdef USE_NEW_DYNAREC + CPU_K6_2, + CPU_K6_2C, + CPU_K6_3, + CPU_K6_2P, + CPU_K6_3P, +#endif +#if defined(DEV_BRANCH) && defined(USE_I686) + CPU_PENTIUMPRO, /* 686 class CPUs */ + CPU_PENTIUM2, + CPU_PENTIUM2D, +#endif + CPU_MAX /* Only really needed to close the enum in a way independent of the #ifdef's. */ +}; -#define CPU_8088 0 /* 808x class CPUs */ -#define CPU_8086 1 -#define CPU_286 2 /* 286 class CPUs */ -#define CPU_386SX 3 /* 386 class CPUs */ -#define CPU_386DX 4 -#define CPU_IBM386SLC 5 -#define CPU_IBM486SLC 6 -#define CPU_IBM486BL 7 -#define CPU_RAPIDCAD 8 -#define CPU_486SLC 9 -#define CPU_486DLC 10 -#define CPU_i486SX 11 /* 486 class CPUs */ -#define CPU_Am486SX 12 -#define CPU_Cx486S 13 -#define CPU_i486DX 14 -#define CPU_Am486DX 15 -#define CPU_Cx486DX 16 -#define CPU_iDX4 17 -#define CPU_Cx5x86 18 -#define CPU_WINCHIP 19 /* 586 class CPUs */ -#define CPU_WINCHIP2 20 -#define CPU_PENTIUM 21 -#define CPU_PENTIUMMMX 22 -#define CPU_Cx6x86 23 -#define CPU_Cx6x86MX 24 -#define CPU_Cx6x86L 25 -#define CPU_CxGX1 26 -#define CPU_K5 27 -#define CPU_5K86 28 -#define CPU_K6 29 -#define CPU_K6_2 30 -#define CPU_K6_2C 31 -#define CPU_K6_3 32 -#define CPU_K6_2P 33 -#define CPU_K6_3P 34 -#define CPU_PENTIUMPRO 35 /* 686 class CPUs */ -#define CPU_PENTIUM2D 36 - #define MANU_INTEL 0 #define MANU_AMD 1 #define MANU_CYRIX 2 #define MANU_IDT 3 +#define MANU_NEC 4 #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 @@ -71,20 +97,20 @@ typedef struct { - const char*name; - int cpu_type; - int rspeed; - double multi; - int pci_speed; - uint32_t edx_reset; - uint32_t cpuid_model; - uint16_t cyrix_id; - uint8_t cpu_flags; - int8_t mem_read_cycles, mem_write_cycles; - int8_t cache_read_cycles, cache_write_cycles; - int8_t atclk_div; + const char *name; + int cpu_type; + int rspeed; + double multi; + uint32_t edx_reset; + uint32_t cpuid_model; + uint16_t cyrix_id; + uint8_t cpu_flags; + int8_t mem_read_cycles, mem_write_cycles; + int8_t cache_read_cycles, cache_write_cycles; + int8_t atclk_div; } CPU; + extern CPU cpus_8088[]; extern CPU cpus_8086[]; extern CPU cpus_286[]; @@ -104,24 +130,31 @@ extern CPU cpus_i486[]; extern CPU cpus_Am486[]; extern CPU cpus_Cx486[]; extern CPU cpus_WinChip[]; +#ifdef USE_NEW_DYNAREC extern CPU cpus_WinChip_SS7[]; +#endif extern CPU cpus_Pentium5V[]; extern CPU cpus_Pentium5V50[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium3V[]; +extern CPU cpus_Pentium[]; +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))) extern CPU cpus_K5[]; extern CPU cpus_K56[]; +#endif +#ifdef USE_NEW_DYNAREC extern CPU cpus_K56_SS7[]; -extern CPU cpus_Pentium[]; +#endif +#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))) extern CPU cpus_6x863V[]; extern CPU cpus_6x86[]; -extern CPU cpus_6x86SS7[]; -#ifdef DEV_BRANCH -#ifdef USE_I686 -extern CPU cpus_PentiumPro[]; -extern CPU cpus_Pentium2[]; -extern CPU cpus_Pentium2D[]; #endif +#ifdef USE_NEW_DYNAREC +extern CPU cpus_6x86SS7[]; +#endif +#if defined(DEV_BRANCH) && defined(USE_I686) +extern CPU cpus_PentiumPro[]; +extern CPU cpus_PentiumII[]; #endif @@ -180,7 +213,9 @@ typedef union { int16_t sw[4]; uint8_t b[8]; int8_t sb[8]; +#ifdef USE_NEW_DYNAREC float f[2]; +#endif } MMX_REG; typedef struct { @@ -244,12 +279,14 @@ struct _cpustate_ { new_npxc; uint32_t last_ea; +#ifdef USE_NEW_DYNAREC uint32_t old_fp_control, new_fp_control; #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ uint16_t old_fp_control2, new_fp_control2; #endif #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ uint32_t trunc_fp_control; +#endif #endif x86seg seg_cs, @@ -272,9 +309,15 @@ struct _cpustate_ { /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ +#ifdef USE_NEW_DYNAREC #define CPU_STATUS_NOTFLATDS (1 << 8) #define CPU_STATUS_NOTFLATSS (1 << 9) #define CPU_STATUS_MASK 0xff00 +#else +#define CPU_STATUS_NOTFLATDS (1 << 16) +#define CPU_STATUS_NOTFLATSS (1 << 17) +#define CPU_STATUS_MASK 0xffff0000 +#endif #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ @@ -331,12 +374,13 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) /* Global variables. */ extern int cpu_iscyrix; extern int cpu_16bitbus; -extern int cpu_busspeed; +extern int cpu_busspeed, cpu_pci_speed; extern int cpu_multi; +extern double cpu_dmulti; extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ -extern int is8086, is286, is386, is486; +extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4; extern int isibmcpu; extern int is_rapidcad; extern int hasfpu; @@ -348,12 +392,16 @@ extern int hasfpu; #define CPU_FEATURE_CX8 (1 << 5) #define CPU_FEATURE_3DNOW (1 << 6) -extern uint32_t cpu_features; +extern uint32_t cpu_features; -extern int in_smm, smi_line, smi_latched; -extern uint32_t smbase; +extern int in_smm, smi_line, smi_latched; +extern uint32_t smbase; +#ifdef USE_NEW_DYNAREC extern uint16_t cpu_cur_status; +#else +extern uint32_t cpu_cur_status; +#endif extern uint64_t cpu_CR4_mask; extern uint64_t tsc; extern msr_t msr; @@ -372,7 +420,7 @@ extern int ins,output; extern uint32_t pccache; extern uint8_t *pccache2; -extern double bus_timing; +extern double bus_timing, pci_timing; extern uint64_t pmc[2]; extern uint16_t temp_seg_data[4]; extern uint16_t cs_msr; @@ -448,9 +496,14 @@ extern CPU cpus_acer[]; // FIXME: should be in machine file! /* Functions. */ extern int cpu_has_feature(int feature); -int loadseg(uint16_t seg, x86seg *s); -void loadseg_dynarec(uint16_t seg, x86seg *s); -void loadcs(uint16_t seg); +#ifdef USE_NEW_DYNAREC +extern void loadseg_dynarec(uint16_t seg, x86seg *s); +extern int loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); +#else +extern void loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); +#endif extern char *cpu_current_pc(char *bufp); @@ -467,18 +520,24 @@ extern void codegen_reset(void); extern void cpu_set_edx(void); extern int divl(uint32_t val); extern void execx86(int cycs); -extern void enter_smm(); -extern void leave_smm(); +extern void enter_smm(); +extern void leave_smm(); extern void exec386(int cycs); extern void exec386_dynarec(int cycs); extern int idivl(int32_t val); -void pmodeint(int num, int soft); -int loadseg(uint16_t seg, x86seg *s); -void loadcs(uint16_t seg); -void loadcscall(uint16_t seg, uint32_t old_pc); -void loadcsjmp(uint16_t seg, uint32_t old_pc); -void pmoderetf(int is32, uint16_t off); -void pmodeiret(int is32); +#ifdef USE_NEW_DYNAREC +extern void loadcscall(uint16_t seg, uint32_t old_pc); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +#else +extern void loadcscall(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +#endif extern void resetmcr(void); extern void resetx86(void); extern void refreshread(void); diff --git a/src/cpu/cpu_table.c b/src/cpu_common/cpu_table - Cópia.c similarity index 75% rename from src/cpu/cpu_table.c rename to src/cpu_common/cpu_table - Cópia.c index a0e77f414..2c5676023 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu_common/cpu_table - Cópia.c @@ -45,9 +45,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../machine/machine.h" +#include "machine.h" CPU cpus_8088[] = { @@ -55,10 +55,10 @@ CPU cpus_8088[] = { {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 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} + {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 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} }; CPU cpus_pcjr[] = { @@ -80,9 +80,9 @@ CPU cpus_8086[] = { {"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8086/10", CPU_8086, 10000000, 2, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/12", CPU_8086, 12000000, 3, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/16", CPU_8086, 16000000, 4, 0, 0, 0, 0, 0, 0,0,0,0, 2}, + {"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; @@ -144,20 +144,20 @@ CPU cpus_i386SX[] = { }; CPU cpus_i386DX[] = { - /*i386DX*/ + /*i386DX/RapidCAD*/ {"i386DX/16", CPU_386DX, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, {"i386DX/20", CPU_386DX, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, {"i386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, {"i386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, {"i386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, 0, 4,4,3,3, 3}, - {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, 0, 6,6,3,3, 4}, - {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, 0, 7,7,3,3, 5}, + {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; CPU cpus_Am386SX[] = { - /*Am386*/ + /*Am386SX*/ {"Am386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, {"Am386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, {"Am386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, @@ -167,12 +167,24 @@ CPU cpus_Am386SX[] = { }; CPU cpus_Am386DX[] = { - /*Am386*/ + /*Am386DX*/ {"Am386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, {"Am386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, {"Am386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; + +CPU cpus_486SLC[] = { + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, + {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + CPU cpus_IBM386SLC[] = { /*IBM 386SLC*/ {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0, 0x300, 0, 0, 0, 3,3,3,3, 2}, @@ -182,13 +194,13 @@ CPU cpus_IBM386SLC[] = { }; CPU cpus_IBM486SLC[] = { - /*IBM 486SLC*/ - {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, 0, 6,6,3,3, 4}, + /*IBM 486SLC*/ + {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, 0, 6,6,3,3, 4}, {"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0, 0x400, 0, 0, 0, 7,7,6,6, 5}, - {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6}, - {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8}, - {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 7}, - {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9}, + {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6}, + {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8}, + {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 7}, + {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9}, {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; @@ -201,16 +213,6 @@ CPU cpus_IBM486BL[] = { {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} }; -CPU cpus_486SLC[] = { - /*Cx486SLC*/ - {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, - {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, - {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} -}; CPU cpus_486DLC[] = { /*Cx486DLC*/ @@ -279,17 +281,18 @@ CPU cpus_i486[] = { {"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, {"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, {"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, - {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, - {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/ + {"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, {"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, {"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ {"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, + {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, {"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 5/2, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} }; + CPU cpus_Am486[] = { /*Am486/5x86*/ {"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, @@ -332,8 +335,7 @@ CPU cpus_Cx486[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -#ifdef DEV_BRANCH -#ifdef USE_CYRIX_6X86 +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) CPU cpus_6x863V[] = { /*Cyrix 6x86*/ {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, @@ -370,6 +372,35 @@ CPU cpus_6x86[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; #endif + +#ifdef USE_NEW_DYNAREC + CPU cpus_6x86SS7[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 41666666, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"MII/PR366", CPU_Cx6x86MX, 250000000, 5/2, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"MII/PR400", CPU_Cx6x86MX, 285000000, 3, 31666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; #endif CPU cpus_WinChip[] = { @@ -385,9 +416,43 @@ CPU cpus_WinChip[] = { {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#ifdef USE_NEW_DYNAREC + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, +#endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; +#ifdef USE_NEW_DYNAREC +CPU cpus_WinChip_SS7[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2}, + {"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7/3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ {"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, @@ -466,6 +531,8 @@ CPU cpus_Pentium[] = { {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium MMX*/ {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, @@ -492,8 +559,7 @@ CPU cpus_Pentium[] = { {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -#ifdef DEV_BRANCH -#ifdef USE_AMD_K +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) CPU cpus_K5[] = { /*AMD K5 (Socket 5)*/ {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, @@ -532,9 +598,69 @@ CPU cpus_K56[] = { {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, - {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} -}; +#ifdef USE_NEW_DYNAREC + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, + {"K6-2/366", CPU_K6_2, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, #endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +#ifdef USE_NEW_DYNAREC +CPU cpus_K56_SS7[] = { + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*AMD K6 (Socket 7)*/ + {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*AMD K6-2 (Socket 7/Super Socket 7)*/ + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300", CPU_K6_2, 300000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, + {"K6-2/333", CPU_K6_2, 332500000, 7/2, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, + {"K6-2/350", CPU_K6_2C, 350000000, 7/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, + {"K6-2/366", CPU_K6_2C, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, + {"K6-2/380", CPU_K6_2C, 380000000, 4, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, + {"K6-2/400", CPU_K6_2C, 400000000, 4, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-2/450", CPU_K6_2C, 450000000, 9/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2/475", CPU_K6_2C, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2/500", CPU_K6_2C, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2/533", CPU_K6_2C, 533333333, 11/2, 32323232, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2/550", CPU_K6_2C, 550000000, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + + /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/ + {"K6-2+/450", CPU_K6_2P, 450000000, 9/2, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2+/475", CPU_K6_2P, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2+/500", CPU_K6_2P, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2+/533", CPU_K6_2P, 533333333, 11/2, 32323232, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2+/550", CPU_K6_2P, 550000000, 11/2, 32333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + {"K6-III/400", CPU_K6_3, 400000000, 4, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III/450", CPU_K6_3, 450000000, 9/2, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/400", CPU_K6_3P, 400000000, 4, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III+/450", CPU_K6_3P, 450000000, 9/2, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/475", CPU_K6_3P, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-III+/500", CPU_K6_3P, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; #endif #ifdef DEV_BRANCH diff --git a/src/cpu_common/cpu_table.c b/src/cpu_common/cpu_table.c new file mode 100644 index 000000000..9fa0103fe --- /dev/null +++ b/src/cpu_common/cpu_table.c @@ -0,0 +1,719 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Define all known processor types. + * + * Available cpuspeeds: + * + * 0 = 16 MHz + * 1 = 20 MHz + * 2 = 25 MHz + * 3 = 33 MHz + * 4 = 40 MHz + * 5 = 50 MHz + * 6 = 66 MHz + * 7 = 75 MHz + * 8 = 80 MHz + * 9 = 90 MHz + * 10 = 100 MHz + * 11 = 120 MHz + * 12 = 133 MHz + * 13 = 150 MHz + * 14 = 160 MHz + * 15 = 166 MHz + * 16 = 180 MHz + * 17 = 200 MHz + * + * Version: @(#)cpu_table.c 1.0.7 2019/10/21 + * + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + */ +#include +#include +#include +#include +#include "86box.h" +#include "cpu.h" +#include "machine.h" + + +CPU cpus_8088[] = { + /*8088 standard*/ + {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_pcjr[] = { + /*8088 PCjr*/ + {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_europc[] = { + /*8088 EuroPC*/ + {"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_8086[] = { + /*8086 standard*/ + {"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0,0,0,0, 2}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_pc1512[] = { + /*8086 Amstrad*/ + {"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_286[] = { + /*286*/ + {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ibmat[] = { + /*286*/ + {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 3,3,3,3, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ibmxt286[] = { + /*286*/ + {"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_ps1_m2011[] = { + /*286*/ + {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9} +}; + +CPU cpus_ps2_m30_286[] = { + /*286*/ + {"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_i386SX[] = { + /*i386SX*/ + {"i386SX/16", CPU_386SX, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"i386SX/20", CPU_386SX, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/25", CPU_386SX, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/33", CPU_386SX, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"i386SX/40", CPU_386SX, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_i386DX[] = { + /*i386DX/RapidCAD*/ + {"i386DX/16", CPU_386DX, 16000000, 1, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"i386DX/20", CPU_386DX, 20000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/25", CPU_386DX, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/33", CPU_386DX, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"i386DX/40", CPU_386DX, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_Am386SX[] = { + /*Am386SX*/ + {"Am386SX/16", CPU_386SX, 16000000, 1, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"Am386SX/20", CPU_386SX, 20000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/25", CPU_386SX, 25000000, 1, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/33", CPU_386SX, 33333333, 1, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386SX/40", CPU_386SX, 40000000, 1, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_Am386DX[] = { + /*Am386DX*/ + {"Am386DX/25", CPU_386DX, 25000000, 1, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386DX/33", CPU_386DX, 33333333, 1, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386DX/40", CPU_386DX, 40000000, 1, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_486SLC[] = { + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0x406, 0, 0x0006, 0, 6,6,6,6, 4}, + {"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0x406, 0, 0x0006, 0, 8,8,6,6, 6}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM386SLC[] = { + /*IBM 386SLC*/ + {"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0x300, 0, 0, 0, 3,3,3,3, 2}, + {"386SLC/20", CPU_IBM386SLC, 20000000, 1, 0x300, 0, 0, 0, 4,4,3,3, 3}, + {"386SLC/25", CPU_IBM386SLC, 25000000, 1, 0x300, 0, 0, 0, 4,4,3,3, 3}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486SLC[] = { + /*IBM 486SLC*/ + {"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0x400, 0, 0, 0, 6,6,3,3, 4}, + {"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0x400, 0, 0, 0, 7,7,6,6, 5}, + {"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0x400, 0, 0, 0, 8,8,6,6, 6}, + {"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0x400, 0, 0, 0, 12,12,6,6, 8}, + {"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0x400, 0, 0, 0, 12,12,9,9, 7}, + {"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0x400, 0, 0, 0, 12,12,9,9, 9}, + {"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0x400, 0, 0, 0, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_IBM486BL[] = { + /*IBM Blue Lightning*/ + {"486BL2/50", CPU_IBM486BL, 50000000, 2, 0x400, 0, 0, 0, 8,8,6,6, 6}, + {"486BL2/66", CPU_IBM486BL, 66666666, 2, 0x400, 0, 0, 0, 12,12,6,6, 8}, + {"486BL3/75", CPU_IBM486BL, 75000000, 3, 0x400, 0, 0, 0, 12,12,9,9, 9}, + {"486BL3/100", CPU_IBM486BL, 100000000, 3, 0x400, 0, 0, 0, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0} +}; + +CPU cpus_486DLC[] = { + /*Cx486DLC*/ + {"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3}, + {"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4}, + {"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5}, + {"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4}, + {"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6}, + {"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0x407, 0, 0x0007, 0, 12,12,6,6, 8}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; + +CPU cpus_i486S1[] = { + /*i486*/ + {"i486SX/16", CPU_i486SX, 16000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, + {"i486SX/20", CPU_i486SX, 20000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/25", CPU_i486SX, 25000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486SX2/50", CPU_i486SX2, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486DX/25", CPU_i486DX, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486DX/33", CPU_i486DX, 33333333, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486DX/50", CPU_i486DX, 50000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, + {"i486DX2/40", CPU_i486DX2, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, + {"i486DX2/50", CPU_i486DX2, 50000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/66", CPU_i486DX2, 66666666, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/ + {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; +CPU cpus_Am486S1[] = { + /*Am486*/ + {"Am486SX/33", CPU_Am486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX2, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Am486DX2/66", CPU_Am486DX2, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX2/80", CPU_Am486DX2, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +CPU cpus_Cx486S1[] = { + /*Cyrix 486*/ + {"Cx486S/25", CPU_Cx486S, 25000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, 33333333, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, 40000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX2/50", CPU_Cx486DX2, 50000000, 2, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Cx486DX2/66", CPU_Cx486DX2, 66666666, 2, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Cx486DX2/80", CPU_Cx486DX2, 80000000, 2, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_i486[] = { + /*i486/P24T*/ + {"i486SX/16", CPU_i486SX, 16000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, + {"i486SX/20", CPU_i486SX, 20000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/25", CPU_i486SX, 25000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486SX2/50", CPU_i486SX, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486DX/25", CPU_i486DX2, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486DX/33", CPU_i486DX, 33333333, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486DX/50", CPU_i486DX, 50000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, + {"i486DX2/40", CPU_i486DX2, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/ + {"i486DX2/50", CPU_i486DX2, 50000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486DX2/66", CPU_i486DX2, 66666666, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, + {"iDX4/75", CPU_iDX4, 75000000, 3, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 100000000, 3, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, + {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, + {"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, + {"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 5/2, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0} +}; + +CPU cpus_Am486[] = { + /*Am486/5x86*/ + {"Am486SX/33", CPU_Am486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX/33", CPU_Am486DX, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX2, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Am486DX2/66", CPU_Am486DX2, 66666666, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486DX2/80", CPU_Am486DX2, 80000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Am486DX4/75", CPU_Am486DX4, 75000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"Am486DX4/90", CPU_Am486DX4, 90000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Am486DX4/100", CPU_Am486DX4, 100000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Am486DX4/120", CPU_Am486DX4, 120000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, + {"Am5x86/P75", CPU_Am5x86, 133333333, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"Am5x86/P75+", CPU_Am5x86, 150000000, 3, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/ + {"Am5x86/P90", CPU_Am5x86, 160000000, 4, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/ + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Cx486[] = { + /*Cyrix 486*/ + {"Cx486S/25", CPU_Cx486S, 25000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, 33333333, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, 40000000, 1, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX2/50", CPU_Cx486DX2, 50000000, 2, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"Cx486DX2/66", CPU_Cx486DX2, 66666666, 2, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Cx486DX2/80", CPU_Cx486DX2, 80000000, 2, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, + {"Cx486DX4/75", CPU_Cx486DX4, 75000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, + {"Cx486DX4/100", CPU_Cx486DX4, 100000000, 3, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + + /*Cyrix 5x86*/ + {"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/ + {"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12}, + {"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15}, + {"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) +CPU cpus_6x863V[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_6x86[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; +#endif + +#ifdef USE_NEW_DYNAREC + CPU cpus_6x86SS7[] = { + /*Cyrix 6x86*/ + {"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10}, + {"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86L*/ + {"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14}, + {"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18}, + + /*Cyrix 6x86MX/MII*/ + {"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2}, + {"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, + {"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30}, + {"MII/PR366", CPU_Cx6x86MX, 250000000, 5/2, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30}, + {"MII/PR400", CPU_Cx6x86MX, 285000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34}, + {"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }; +#endif + +CPU cpus_WinChip[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, 120000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, 133333333, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, 180000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, 200000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, 225000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, 240000000, 4, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, +#ifdef USE_NEW_DYNAREC + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2}, +#endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#ifdef USE_NEW_DYNAREC +CPU cpus_WinChip_SS7[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9}, + {"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2}, + {"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12}, + {"WinChip 120", CPU_WINCHIP, 120000000, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14}, + {"WinChip 133", CPU_WINCHIP, 133333333, 2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16}, + {"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2}, + {"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40}, + {"WinChip 180", CPU_WINCHIP, 180000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21}, + {"WinChip 200", CPU_WINCHIP, 200000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, + {"WinChip 225", CPU_WINCHIP, 225000000, 3, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27}, + {"WinChip 240", CPU_WINCHIP, 240000000, 4, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, + {"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2}, + {"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7/3, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +CPU cpus_Pentium5V[] = { + /*Intel Pentium (5V, socket 4)*/ + {"Pentium 60", CPU_PENTIUM, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, + {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium5V50[] = { + /*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/ + {"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6}, + {"Pentium 60", CPU_PENTIUM, 60000000, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, 66666666, 1, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8}, + {"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12}, + {"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumS5[] = { + /*Intel Pentium (Socket 5)*/ + {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12}, + {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"Pentium 120", CPU_PENTIUM, 120000000, 2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16}, + {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium3V[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"Pentium 120", CPU_PENTIUM, 120000000, 2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Pentium 133", CPU_PENTIUM, 133333333, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium 200", CPU_PENTIUM, 200000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_Pentium[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, + {"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"Pentium 120", CPU_PENTIUM, 120000000, 2, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Pentium 133", CPU_PENTIUM, 133333333, 2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium 200", CPU_PENTIUM, 200000000, 3, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium MMX*/ + {"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + + /*Mobile Pentium*/ + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 5/2, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 9/2, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*Intel Pentium OverDrive*/ + {"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)) +CPU cpus_K5[] = { + /*AMD K5 (Socket 5)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_K56[] = { + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*AMD K6 (Socket 7*/ + {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, +#ifdef USE_NEW_DYNAREC + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36}, + {"K6-2/366", CPU_K6_2, 366666666, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44}, +#endif + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +#ifdef USE_NEW_DYNAREC +CPU cpus_K56_SS7[] = { + /*AMD K5 (Socket 7)*/ + {"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2}, + {"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, + {"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14}, + {"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, + {"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*AMD K6 (Socket 7)*/ + {"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"K6 (Model 6) 200", CPU_K6, 200000000, 3, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 200", CPU_K6, 200000000, 3, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + {"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6 (Model 7) 266", CPU_K6, 266666666, 4, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + + /*AMD K6-2 (Socket 7/Super Socket 7)*/ + {"K6-2/233", CPU_K6_2, 233333333, 7/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, 266666666, 4, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300", CPU_K6_2, 300000000, 3, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36}, + {"K6-2/333", CPU_K6_2, 332500000, 7/2, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40}, + {"K6-2/350", CPU_K6_2C, 350000000, 7/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42}, + {"K6-2/366", CPU_K6_2C, 366666666, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44}, + {"K6-2/380", CPU_K6_2C, 380000000, 4, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46}, + {"K6-2/400", CPU_K6_2C, 400000000, 4, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-2/450", CPU_K6_2C, 450000000, 9/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2/475", CPU_K6_2C, 475000000, 5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2/500", CPU_K6_2C, 500000000, 5, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2/533", CPU_K6_2C, 533333333, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2/550", CPU_K6_2C, 550000000, 11/2, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + + /*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/ + {"K6-2+/450", CPU_K6_2P, 450000000, 9/2, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-2+/475", CPU_K6_2P, 475000000, 5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-2+/500", CPU_K6_2P, 500000000, 5, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"K6-2+/533", CPU_K6_2P, 533333333, 11/2, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64}, + {"K6-2+/550", CPU_K6_2P, 550000000, 11/2, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66}, + {"K6-III/400", CPU_K6_3, 400000000, 4, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III/450", CPU_K6_3, 450000000, 9/2, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/400", CPU_K6_3P, 400000000, 4, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48}, + {"K6-III+/450", CPU_K6_3P, 450000000, 9/2, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54}, + {"K6-III+/475", CPU_K6_3P, 475000000, 5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57}, + {"K6-III+/500", CPU_K6_3P, 500000000, 5, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif + +#ifdef DEV_BRANCH +#ifdef USE_I686 +CPU cpus_PentiumPro[] = { + /*Intel Pentium Pro*/ + {"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 3/2, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 5/2, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, + {"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 5/2, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, + {"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, + + /*Intel Pentium II OverDrive*/ + {"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 3/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 7/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25}, + {"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 7/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 9/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33}, + {"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 9/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +CPU cpus_PentiumII[] = { + /*Intel Pentium II Klamath*/ + {"Pentium II Klamath 50", CPU_PENTIUM2, 50000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Klamath 60", CPU_PENTIUM2, 60000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Klamath 66", CPU_PENTIUM2, 66666666, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Klamath 75", CPU_PENTIUM2, 75000000, 3/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Klamath 233", CPU_PENTIUM2, 233333333, 7/2, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"Pentium II Klamath 266", CPU_PENTIUM2, 266666666, 4, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Klamath 300/66", CPU_PENTIUM2, 300000000, 9/2, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + + /*Intel Pentium II Deschutes*/ + {"Pentium II Deschutes 50", CPU_PENTIUM2D, 50000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, + {"Pentium II Deschutes 60", CPU_PENTIUM2D, 60000000, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium II Deschutes 66", CPU_PENTIUM2D, 66666666, 1, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium II Deschutes 75", CPU_PENTIUM2D, 75000000, 3/2, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"Pentium II Deschutes 266", CPU_PENTIUM2D, 266666666, 4, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29}, + {"Pentium II Deschutes 300/66", CPU_PENTIUM2D, 300000000, 9/2, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"Pentium II Deschutes 333", CPU_PENTIUM2D, 333333333, 5, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"Pentium II Deschutes 350", CPU_PENTIUM2D, 350000000, 7/2, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,11,11, 42}, + {"Pentium II Deschutes 400", CPU_PENTIUM2D, 400000000, 4, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, + {"Pentium II Deschutes 450", CPU_PENTIUM2D, 450000000, 9/2, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54}, + {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +#endif +#endif diff --git a/src/cpu/x86.h b/src/cpu_common/x86.h similarity index 96% rename from src/cpu/x86.h rename to src/cpu_common/x86.h index cf664a8b1..e3505a2e2 100644 --- a/src/cpu/x86.h +++ b/src/cpu_common/x86.h @@ -1,7 +1,3 @@ -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/x86.h" -#else - extern uint8_t opcode, opcode2; extern uint8_t flags_p; extern uint8_t znptable8[256]; @@ -72,4 +68,3 @@ extern void x86_doabrt(int x86_abrt); extern void x86illegal(); extern void x86seg_reset(); extern void x86gpf(char *s, uint16_t error); -#endif diff --git a/src/cpu/x86_ops.h b/src/cpu_common/x86_ops.h similarity index 89% rename from src/cpu/x86_ops.h rename to src/cpu_common/x86_ops.h index 2c4a2f3e5..afbdafde7 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu_common/x86_ops.h @@ -70,6 +70,9 @@ extern const OpFn *x86_dynarec_opcodes_df_a16; extern const OpFn *x86_dynarec_opcodes_df_a32; extern const OpFn *x86_dynarec_opcodes_REPE; extern const OpFn *x86_dynarec_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC +extern const OpFn *x86_dynarec_opcodes_3DNOW; +#endif extern const OpFn dynarec_ops_286[1024]; extern const OpFn dynarec_ops_286_0f[1024]; @@ -80,15 +83,25 @@ extern const OpFn dynarec_ops_386_0f[1024]; extern const OpFn dynarec_ops_486_0f[1024]; extern const OpFn dynarec_ops_winchip_0f[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn dynarec_ops_winchip2_0f[1024]; +#endif extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) extern const OpFn dynarec_ops_c6x86mx_0f[1024]; #endif +#ifdef USE_NEW_DYNAREC +extern const OpFn dynarec_ops_k6_0f[1024]; +extern const OpFn dynarec_ops_k62_0f[1024]; +#endif + #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn dynarec_ops_pentiumpro_0f[1024]; +extern const OpFn dynarec_ops_pentium2_0f[1024]; extern const OpFn dynarec_ops_pentium2d_0f[1024]; #endif @@ -135,6 +148,9 @@ extern const OpFn dynarec_ops_fpu_686_df_a32[256]; extern const OpFn dynarec_ops_REPE[1024]; extern const OpFn dynarec_ops_REPNE[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn dynarec_ops_3DNOW[256]; +#endif #else void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f); #endif @@ -159,6 +175,9 @@ extern const OpFn *x86_opcodes_df_a16; extern const OpFn *x86_opcodes_df_a32; extern const OpFn *x86_opcodes_REPE; extern const OpFn *x86_opcodes_REPNE; +#ifdef USE_NEW_DYNAREC +extern const OpFn *x86_opcodes_3DNOW; +#endif extern const OpFn ops_286[1024]; extern const OpFn ops_286_0f[1024]; @@ -169,16 +188,25 @@ extern const OpFn ops_386_0f[1024]; extern const OpFn ops_486_0f[1024]; extern const OpFn ops_winchip_0f[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn ops_winchip2_0f[1024]; +#endif extern const OpFn ops_pentium_0f[1024]; extern const OpFn ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)) extern const OpFn ops_c6x86mx_0f[1024]; #endif +#ifdef USE_NEW_DYNAREC +extern const OpFn ops_k6_0f[1024]; +extern const OpFn ops_k62_0f[1024]; +#endif + #if defined(DEV_BRANCH) && defined(USE_I686) extern const OpFn ops_pentiumpro_0f[1024]; +extern const OpFn ops_pentium2_0f[1024]; extern const OpFn ops_pentium2d_0f[1024]; #endif @@ -225,5 +253,13 @@ extern const OpFn ops_fpu_686_df_a32[256]; extern const OpFn ops_REPE[1024]; extern const OpFn ops_REPNE[1024]; +#ifdef USE_NEW_DYNAREC +extern const OpFn ops_3DNOW[256]; +#endif + +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) #endif /*_X86_OPS_H*/ diff --git a/src/cpu_common/x86_ops_3dnow.h b/src/cpu_common/x86_ops_3dnow.h new file mode 100644 index 000000000..c578c400a --- /dev/null +++ b/src/cpu_common/x86_ops_3dnow.h @@ -0,0 +1,346 @@ +#include + +static int opPREFETCH_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} +static int opPREFETCH_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} + +static int opFEMMS(uint32_t fetchdat) +{ + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); + if (cr0 & 0xc) + { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; +} + +static int opPAVGUSB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + + return 0; +} +static int opPF2ID(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; + + return 0; +} +static int opPFACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int opPFADD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; + + return 0; +} +static int opPFCMPEQ(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFCMPGE(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFCMPGT(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFMAX(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFMIN(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFMUL(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + + return 0; +} +static int opPFRCP(uint32_t fetchdat) +{ + union + { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) + { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + + cpu_state.MM[cpu_reg].f[0] = 1.0/src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + + return 0; +} +/*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ +static int opPFRCPIT1(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFRCPIT2(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFRSQRT(uint32_t fetchdat) +{ + union + { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) + { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + + cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + + return 0; +} +/*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ +static int opPFRSQIT1(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + UN_USED(src); + + return 0; +} +static int opPFSUB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + + return 0; +} +static int opPFSUBR(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + + return 0; +} +static int opPI2FD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; + + return 0; +} +static int opPMULHRW(uint32_t fetchdat) +{ + if (cpu_mod == 3) + { + cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } + else + { + MMX_REG src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; +} + +const OpFn OP_TABLE(3DNOW)[256] = +{ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL, +/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL, +/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +static int op3DNOW_a16(uint32_t fetchdat) +{ + uint8_t opcode; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + return x86_opcodes_3DNOW[opcode](0); +} +static int op3DNOW_a32(uint32_t fetchdat) +{ + uint8_t opcode; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + return x86_opcodes_3DNOW[opcode](0); +} diff --git a/src/cpu_common/x86_ops_amd.h b/src/cpu_common/x86_ops_amd.h new file mode 100644 index 000000000..8f003e1fb --- /dev/null +++ b/src/cpu_common/x86_ops_amd.h @@ -0,0 +1,192 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * AMD SYSCALL and SYSRET CPU Instructions. + * + * Version: @(#)x86_ops_amd.h 1.0.4 2018/10/17 + * + * Author: Miran Grca, + * Copyright 2016-2018 Miran Grca. + */ + +/* 0 = Limit 0-15 + 1 = Base 0-15 + 2 = Base 16-23 (bits 0-7), Access rights + 8-11 Type + 12 S + 13, 14 DPL + 15 P + 3 = Limit 16-19 (bits 0-3), Base 24-31 (bits 8-15), granularity, etc. + 4 A + 6 DB + 7 G */ + +#define AMD_SYSCALL_EIP (star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((star >> 48) & 0xFFFF) + +/* 0F 05 */ +static int opSYSCALL(uint32_t fetchdat) +{ + uint16_t syscall_cs_seg_data[4] = {0, 0, 0, 0}; + uint16_t syscall_ss_seg_data[4] = {0, 0, 0, 0}; + + if (!(cr0 & 1)) return internal_illegal("SYSCALL: CPU not in protected mode"); + if (!AMD_SYSCALL_SB) return internal_illegal("SYSCALL: AMD SYSCALL SB MSR is zero"); + + /* Set VM, IF, RF to 0. */ + /* cpu_state.eflags &= ~0x00030200; + cpu_state.flags &= ~0x0200; */ + + /* Let's do this by the AMD spec. */ + ECX = cpu_state.pc; + + cpu_state.eflags &= ~0x0002; + cpu_state.flags &= ~0x0200; + + /* CS */ + cpu_state.seg_cs.seg = AMD_SYSCALL_SB & ~7; + if (AMD_SYSCALL_SB & 4) + { + if (cpu_state.seg_cs.seg >= ldt.limit) + { + x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSCALL_SB,ldt.limit); + x86gpf(NULL, AMD_SYSCALL_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg +=ldt.base; + } + else + { + if (cpu_state.seg_cs.seg >= gdt.limit) + { + x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSCALL_SB,gdt.limit); + x86gpf(NULL, AMD_SYSCALL_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg += gdt.base; + } + cpl_override = 1; + + syscall_cs_seg_data[0] = 0xFFFF; + syscall_cs_seg_data[1] = 0; + syscall_cs_seg_data[2] = 0x9B00; + syscall_cs_seg_data[3] = 0xC0; + + cpl_override = 0; + + use32 = 0x300; + CS = (AMD_SYSCALL_SB & ~3) | 0; + + do_seg_load(&cpu_state.seg_cs, syscall_cs_seg_data); + use32 = 0x300; + + CS = (CS & 0xFFFC) | 0; + + cpu_state.seg_cs.limit = 0xFFFFFFFF; + cpu_state.seg_cs.limit_high = 0xFFFFFFFF; + + /* SS */ + syscall_ss_seg_data[0] = 0xFFFF; + syscall_ss_seg_data[1] = 0; + syscall_ss_seg_data[2] = 0x9300; + syscall_ss_seg_data[3] = 0xC0; + do_seg_load(&cpu_state.seg_ss, syscall_ss_seg_data); + cpu_state.seg_ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC; + stack32 = 1; + + cpu_state.seg_ss.limit = 0xFFFFFFFF; + cpu_state.seg_ss.limit_high = 0xFFFFFFFF; + + cpu_state.seg_ss.checked = 0; + + cpu_state.pc = AMD_SYSCALL_EIP; + + CLOCK_CYCLES(20); + + CPU_BLOCK_END(); + + return 0; +} + +/* 0F 07 */ +static int opSYSRET(uint32_t fetchdat) +{ + uint16_t sysret_cs_seg_data[4] = {0, 0, 0, 0}; + uint16_t sysret_ss_seg_data[4] = {0, 0, 0, 0}; + + if (!AMD_SYSRET_SB) return internal_illegal("SYSRET: CS MSR is zero"); + if (!(cr0 & 1)) return internal_illegal("SYSRET: CPU not in protected mode"); + + cpu_state.pc = ECX; + + cpu_state.eflags |= (1 << 1); + + /* CS */ + cpu_state.seg_cs.seg = AMD_SYSRET_SB & ~7; + if (AMD_SYSRET_SB & 4) + { + if (cpu_state.seg_cs.seg >= ldt.limit) + { + x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSRET_SB,ldt.limit); + x86gpf(NULL, AMD_SYSRET_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg +=ldt.base; + } + else + { + if (cpu_state.seg_cs.seg >= gdt.limit) + { + x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSRET_SB,gdt.limit); + x86gpf(NULL, AMD_SYSRET_SB & ~3); + return 1; + } + cpu_state.seg_cs.seg += gdt.base; + } + cpl_override = 1; + + sysret_cs_seg_data[0] = 0xFFFF; + sysret_cs_seg_data[1] = 0; + sysret_cs_seg_data[2] = 0xFB00; + sysret_cs_seg_data[3] = 0xC0; + + cpl_override = 0; + + use32 = 0x300; + CS = (AMD_SYSRET_SB & ~3) | 3; + + do_seg_load(&cpu_state.seg_cs, sysret_cs_seg_data); + flushmmucache_cr3(); + use32 = 0x300; + + CS = (CS & 0xFFFC) | 3; + + cpu_state.seg_cs.limit = 0xFFFFFFFF; + cpu_state.seg_cs.limit_high = 0xFFFFFFFF; + + /* SS */ + sysret_ss_seg_data[0] = 0xFFFF; + sysret_ss_seg_data[1] = 0; + sysret_ss_seg_data[2] = 0xF300; + sysret_ss_seg_data[3] = 0xC0; + do_seg_load(&cpu_state.seg_ss, sysret_ss_seg_data); + cpu_state.seg_ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3; + stack32 = 1; + + cpu_state.seg_ss.limit = 0xFFFFFFFF; + cpu_state.seg_ss.limit_high = 0xFFFFFFFF; + + cpu_state.seg_ss.checked = 0; + + CLOCK_CYCLES(20); + + CPU_BLOCK_END(); + + return 0; +} diff --git a/src/cpu/x86_ops_arith.h b/src/cpu_common/x86_ops_arith.h similarity index 99% rename from src/cpu/x86_ops_arith.h rename to src/cpu_common/x86_ops_arith.h index 80a0da788..489fd5e57 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu_common/x86_ops_arith.h @@ -718,6 +718,8 @@ static int op81_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); if ((rmdat & 0x38) == 0x38) diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu_common/x86_ops_atomic.h similarity index 92% rename from src/cpu/x86_ops_atomic.h rename to src/cpu_common/x86_ops_atomic.h index c490d747a..4011a0aa4 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu_common/x86_ops_atomic.h @@ -8,7 +8,7 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; if (AL == temp) seteab(getr8(cpu_reg)); else AL = temp; @@ -27,7 +27,7 @@ static int opCMPXCHG_b_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; if (AL == temp) seteab(getr8(cpu_reg)); else AL = temp; @@ -47,7 +47,7 @@ static int opCMPXCHG_w_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); else AX = temp; @@ -66,7 +66,7 @@ static int opCMPXCHG_w_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); else AX = temp; @@ -86,7 +86,7 @@ static int opCMPXCHG_l_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); else EAX = temp; @@ -105,7 +105,7 @@ static int opCMPXCHG_l_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); else EAX = temp; @@ -125,7 +125,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat) return 0; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; if (EAX == temp && EDX == temp_hi) @@ -143,7 +143,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat) if (temp == temp2 && temp_hi == temp2_hi) cpu_state.flags |= Z_FLAG; else - cpu_state.flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } @@ -157,7 +157,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) return 0; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; if (EAX == temp && EDX == temp_hi) @@ -175,7 +175,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) if (temp == temp2 && temp_hi == temp2_hi) cpu_state.flags |= Z_FLAG; else - cpu_state.flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } @@ -190,7 +190,7 @@ static int opXADD_b_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; setadd8(temp, getr8(cpu_reg)); @@ -208,7 +208,7 @@ static int opXADD_b_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; setadd8(temp, getr8(cpu_reg)); @@ -227,7 +227,7 @@ static int opXADD_w_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; setadd16(temp, cpu_state.regs[cpu_reg].w); @@ -245,7 +245,7 @@ static int opXADD_w_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; setadd16(temp, cpu_state.regs[cpu_reg].w); @@ -264,7 +264,7 @@ static int opXADD_l_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; setadd32(temp, cpu_state.regs[cpu_reg].l); @@ -282,7 +282,7 @@ static int opXADD_l_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; setadd32(temp, cpu_state.regs[cpu_reg].l); diff --git a/src/cpu_new/x86_ops_bcd.h b/src/cpu_common/x86_ops_bcd.h similarity index 100% rename from src/cpu_new/x86_ops_bcd.h rename to src/cpu_common/x86_ops_bcd.h diff --git a/src/cpu/x86_ops_bit.h b/src/cpu_common/x86_ops_bit.h similarity index 94% rename from src/cpu/x86_ops_bit.h rename to src/cpu_common/x86_ops_bit.h index 42d9aa4aa..df2d48619 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu_common/x86_ops_bit.h @@ -3,12 +3,12 @@ static int opBT_w_r_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); @@ -19,12 +19,12 @@ static int opBT_w_r_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); @@ -35,12 +35,12 @@ static int opBT_l_r_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); @@ -51,12 +51,12 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); @@ -161,7 +161,7 @@ static int opBA_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteaw(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -185,7 +185,6 @@ static int opBA_w_a16(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -205,7 +204,7 @@ static int opBA_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteaw(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -229,7 +228,6 @@ static int opBA_w_a32(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -250,7 +248,7 @@ static int opBA_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteal(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -274,7 +272,6 @@ static int opBA_l_a16(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -294,7 +291,7 @@ static int opBA_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); - + temp = geteal(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -318,7 +315,6 @@ static int opBA_l_a32(uint32_t fetchdat) break; default: - x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; diff --git a/src/cpu_new/x86_ops_bitscan.h b/src/cpu_common/x86_ops_bitscan.h similarity index 99% rename from src/cpu_new/x86_ops_bitscan.h rename to src/cpu_common/x86_ops_bitscan.h index 01d9c5795..46f0fc605 100644 --- a/src/cpu_new/x86_ops_bitscan.h +++ b/src/cpu_common/x86_ops_bitscan.h @@ -73,7 +73,7 @@ static int opBSF_l_a16(uint32_t fetchdat) static int opBSF_l_a32(uint32_t fetchdat) { uint32_t temp; - int instr_cycles = 0; + int instr_cycles = 0; fetch_ea_32(fetchdat); if (cpu_mod != 3) diff --git a/src/cpu/x86_ops_flag.h b/src/cpu_common/x86_ops_flag.h similarity index 98% rename from src/cpu/x86_ops_flag.h rename to src/cpu_common/x86_ops_flag.h index 8441b4987..099f2e35f 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu_common/x86_ops_flag.h @@ -99,7 +99,7 @@ static int opSAHF(uint32_t fetchdat) CLOCK_CYCLES(3); PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif @@ -182,7 +182,7 @@ static int opPOPF_286(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif @@ -242,7 +242,7 @@ static int opPOPF(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif @@ -276,7 +276,7 @@ static int opPOPFD(uint32_t fetchdat) CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); -#if 0 +#ifdef USE_NEW_DYNAREC codegen_flags_changed = 0; #endif diff --git a/src/cpu_new/x86_ops_fpu.h b/src/cpu_common/x86_ops_fpu.h similarity index 72% rename from src/cpu_new/x86_ops_fpu.h rename to src/cpu_common/x86_ops_fpu.h index 8c264374f..690357511 100644 --- a/src/cpu_new/x86_ops_fpu.h +++ b/src/cpu_common/x86_ops_fpu.h @@ -1,72 +1,91 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ static int opESCAPE_d8_a16(uint32_t fetchdat) { + pclog("A16: D8 %02X\n", fetchdat & 0xff); return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_d8_a32(uint32_t fetchdat) { + pclog("A32: D8 %02X\n", fetchdat & 0xff); return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_d9_a16(uint32_t fetchdat) { + pclog("A16: D9 %02X\n", fetchdat & 0xff); return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_d9_a32(uint32_t fetchdat) { + pclog("A32: D9 %02X\n", fetchdat & 0xff); return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); } static int opESCAPE_da_a16(uint32_t fetchdat) { + pclog("A16: DA %02X\n", fetchdat & 0xff); return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_da_a32(uint32_t fetchdat) { + pclog("A32: DA %02X\n", fetchdat & 0xff); return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); } static int opESCAPE_db_a16(uint32_t fetchdat) { + pclog("A16: DB %02X\n", fetchdat & 0xff); return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_db_a32(uint32_t fetchdat) { + pclog("A32: DB %02X\n", fetchdat & 0xff); return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); } static int opESCAPE_dc_a16(uint32_t fetchdat) { + pclog("A16: DC %02X\n", fetchdat & 0xff); return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_dc_a32(uint32_t fetchdat) { + pclog("A32: DC %02X\n", fetchdat & 0xff); return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_dd_a16(uint32_t fetchdat) { + pclog("A16: DD %02X\n", fetchdat & 0xff); return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_dd_a32(uint32_t fetchdat) { + pclog("A32: DD %02X\n", fetchdat & 0xff); return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); } static int opESCAPE_de_a16(uint32_t fetchdat) { + pclog("A16: DE %02X\n", fetchdat & 0xff); return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_de_a32(uint32_t fetchdat) { + pclog("A32: DE %02X\n", fetchdat & 0xff); return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); } static int opESCAPE_df_a16(uint32_t fetchdat) { + pclog("A16: DF %02X\n", fetchdat & 0xff); return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_df_a32(uint32_t fetchdat) { + pclog("A32: DF %02X\n", fetchdat & 0xff); return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); } diff --git a/src/cpu/x86_ops_i686.h b/src/cpu_common/x86_ops_i686.h similarity index 96% rename from src/cpu/x86_ops_i686.h rename to src/cpu_common/x86_ops_i686.h index 6d4cf7484..2b34e0822 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu_common/x86_ops_i686.h @@ -8,10 +8,10 @@ * * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. * - * Version: @(#)x86_ops_i686.h 1.0.5 2018/10/17 + * Version: @(#)x86_ops_i686.h 1.0.6 2020/01/27 * * Author: Miran Grca, - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2020 Miran Grca. */ /* 0 = Limit 0-15 @@ -63,8 +63,8 @@ static int opSYSENTER(uint32_t fetchdat) cgate16 = cgate32 = 0; \ /* Set VM, RF, and IF to 0. */ - cpu_state.eflags &= ~(VM_FLAG | 0x0001); - cpu_state.flags &= ~I_FLAG; + cpu_state.eflags &= ~0x0003; + cpu_state.flags &= ~0x0200; CS = (cs_msr & 0xFFFC); make_seg_data(sysenter_cs_seg_data, 0, 0xFFFFF, 11, 1, 0, 1, 1, 1, 0); @@ -190,8 +190,14 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -314,6 +320,9 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; @@ -368,8 +377,14 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) { /* FXRSTOR */ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.TOP = (fpus >> 11) & 7; cpu_state.npxs &= fpus & ~0x3800; @@ -492,6 +507,9 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; cpu_state.npxc = 0x37F; +#ifdef USE_NEW_DYNAREC + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#endif cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; diff --git a/src/cpu_new/x86_ops_inc_dec.h b/src/cpu_common/x86_ops_inc_dec.h similarity index 97% rename from src/cpu_new/x86_ops_inc_dec.h rename to src/cpu_common/x86_ops_inc_dec.h index d14bae863..ff4a4ab73 100644 --- a/src/cpu_new/x86_ops_inc_dec.h +++ b/src/cpu_common/x86_ops_inc_dec.h @@ -49,7 +49,7 @@ static int opINCDEC_b_a16(uint32_t fetchdat) { uint8_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); temp=geteab(); if (cpu_state.abrt) return 1; @@ -72,7 +72,7 @@ static int opINCDEC_b_a32(uint32_t fetchdat) { uint8_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); temp=geteab(); if (cpu_state.abrt) return 1; diff --git a/src/cpu_new/x86_ops_int.h b/src/cpu_common/x86_ops_int.h similarity index 100% rename from src/cpu_new/x86_ops_int.h rename to src/cpu_common/x86_ops_int.h diff --git a/src/cpu_new/x86_ops_io.h b/src/cpu_common/x86_ops_io.h similarity index 100% rename from src/cpu_new/x86_ops_io.h rename to src/cpu_common/x86_ops_io.h diff --git a/src/cpu/x86_ops_jump.h b/src/cpu_common/x86_ops_jump.h similarity index 90% rename from src/cpu/x86_ops_jump.h rename to src/cpu_common/x86_ops_jump.h index 6eb9862af..c227939a3 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu_common/x86_ops_jump.h @@ -23,6 +23,8 @@ if (cond_ ## condition) \ { \ cpu_state.pc += offset; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ CLOCK_CYCLES_ALWAYS(timing_bt); \ CPU_BLOCK_END(); \ PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ @@ -40,6 +42,7 @@ if (cond_ ## condition) \ { \ cpu_state.pc += offset; \ + cpu_state.pc &= 0xffff; \ CLOCK_CYCLES_ALWAYS(timing_bt); \ CPU_BLOCK_END(); \ PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ @@ -95,6 +98,8 @@ static int opLOOPNE_w(uint32_t fetchdat) if (CX && !ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -110,6 +115,8 @@ static int opLOOPNE_l(uint32_t fetchdat) if (ECX && !ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -126,6 +133,8 @@ static int opLOOPE_w(uint32_t fetchdat) if (CX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -141,6 +150,8 @@ static int opLOOPE_l(uint32_t fetchdat) if (ECX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -157,6 +168,8 @@ static int opLOOP_w(uint32_t fetchdat) if (CX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -172,6 +185,8 @@ static int opLOOP_l(uint32_t fetchdat) if (ECX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -186,6 +201,8 @@ static int opJCXZ(uint32_t fetchdat) if (!CX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); @@ -202,6 +219,8 @@ static int opJECXZ(uint32_t fetchdat) if (!ECX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); @@ -217,6 +236,8 @@ static int opJMP_r8(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); @@ -227,6 +248,7 @@ static int opJMP_r16(uint32_t fetchdat) { int16_t offset = (int16_t)getwordf(); cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); @@ -278,6 +300,7 @@ static int opCALL_r16(uint32_t fetchdat) int16_t addr = (int16_t)getwordf(); PUSH_W(cpu_state.pc); cpu_state.pc += addr; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); diff --git a/src/cpu_new/x86_ops_misc.h b/src/cpu_common/x86_ops_misc.h similarity index 99% rename from src/cpu_new/x86_ops_misc.h rename to src/cpu_common/x86_ops_misc.h index e49825a5f..91118211b 100644 --- a/src/cpu_new/x86_ops_misc.h +++ b/src/cpu_common/x86_ops_misc.h @@ -616,7 +616,7 @@ static int opHLT(uint32_t fetchdat) { CLOCK_CYCLES_ALWAYS(100); if (!((cpu_state.flags & I_FLAG) && pic_intpending)) - cpu_state.pc--; + cpu_state.pc--; } else CLOCK_CYCLES(5); @@ -964,6 +964,7 @@ static int opRSM(uint32_t fetchdat) { leave_smm(); if(smi_latched) enter_smm(); + CPU_BLOCK_END(); return 0; } cpu_state.pc = cpu_state.oldpc; diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu_common/x86_ops_mmx.h similarity index 95% rename from src/cpu/x86_ops_mmx.h rename to src/cpu_common/x86_ops_mmx.h index 107710f77..f9a7f9357 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu_common/x86_ops_mmx.h @@ -11,7 +11,7 @@ } \ else \ { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ CLOCK_CYCLES(2); \ } @@ -38,7 +38,7 @@ static int opEMMS(uint32_t fetchdat) x86illegal(); return 1; } - if (cr0 & 4) + if (cr0 & 0xc) { x86_int(7); return 1; diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu_common/x86_ops_mmx_arith.h similarity index 99% rename from src/cpu/x86_ops_mmx_arith.h rename to src/cpu_common/x86_ops_mmx_arith.h index e8e1f31e5..22c34c738 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu_common/x86_ops_mmx_arith.h @@ -321,7 +321,7 @@ static int opPMULLW_a32(uint32_t fetchdat) else { MMX_REG src; - + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; @@ -350,8 +350,8 @@ static int opPMULHW_a16(uint32_t fetchdat) else { MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; @@ -378,8 +378,8 @@ static int opPMULHW_a32(uint32_t fetchdat) else { MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; diff --git a/src/cpu_new/x86_ops_mmx_cmp.h b/src/cpu_common/x86_ops_mmx_cmp.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_cmp.h rename to src/cpu_common/x86_ops_mmx_cmp.h diff --git a/src/cpu_new/x86_ops_mmx_logic.h b/src/cpu_common/x86_ops_mmx_logic.h similarity index 100% rename from src/cpu_new/x86_ops_mmx_logic.h rename to src/cpu_common/x86_ops_mmx_logic.h diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu_common/x86_ops_mmx_mov.h similarity index 92% rename from src/cpu/x86_ops_mmx_mov.h rename to src/cpu_common/x86_ops_mmx_mov.h index a742941ea..e17721229 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu_common/x86_ops_mmx_mov.h @@ -12,8 +12,8 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat) else { uint32_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].l[0] = dst; cpu_state.MM[cpu_reg].l[1] = 0; @@ -36,8 +36,8 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat) else { uint32_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].l[0] = dst; cpu_state.MM[cpu_reg].l[1] = 0; @@ -59,7 +59,7 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -78,7 +78,7 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -100,7 +100,7 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -120,8 +120,8 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) else { uint64_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -141,7 +141,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu_common/x86_ops_mmx_pack.h similarity index 98% rename from src/cpu/x86_ops_mmx_pack.h rename to src/cpu_common/x86_ops_mmx_pack.h index 170aa0e42..b03ef842e 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu_common/x86_ops_mmx_pack.h @@ -12,7 +12,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].l[1] = src; @@ -33,8 +33,8 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat) else { uint32_t src; - - SEG_CHECK_READ(cpu_state.ea_seg); + + SEG_CHECK_READ(cpu_state.ea_seg); src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].l[1] = src; diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu_common/x86_ops_mmx_shift.h similarity index 97% rename from src/cpu/x86_ops_mmx_shift.h rename to src/cpu_common/x86_ops_mmx_shift.h index edfe16276..a0a4d90c1 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu_common/x86_ops_mmx_shift.h @@ -6,7 +6,7 @@ } \ else \ { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ CLOCK_CYCLES(2); \ } @@ -53,7 +53,6 @@ static int opPSxxW_imm(uint32_t fetchdat) } break; default: - x386_dynarec_log("Bad PSxxW (0F 71) instruction %02X\n", op); cpu_state.pc = cpu_state.oldpc; x86illegal(); return 0; @@ -224,7 +223,6 @@ static int opPSxxD_imm(uint32_t fetchdat) } break; default: - x386_dynarec_log("Bad PSxxD (0F 72) instruction %02X\n", op); cpu_state.pc = cpu_state.oldpc; x86illegal(); return 0; @@ -376,7 +374,6 @@ static int opPSxxQ_imm(uint32_t fetchdat) cpu_state.MM[reg].q <<= shift; break; default: - x386_dynarec_log("Bad PSxxQ (0F 73) instruction %02X\n", op); cpu_state.pc = cpu_state.oldpc; x86illegal(); return 0; diff --git a/src/cpu/x86_ops_mov.h b/src/cpu_common/x86_ops_mov.h similarity index 99% rename from src/cpu/x86_ops_mov.h rename to src/cpu_common/x86_ops_mov.h index cf9bb82c0..dd49465bc 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu_common/x86_ops_mov.h @@ -688,7 +688,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) #define opCMOV(condition) \ static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \ { \ diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu_common/x86_ops_mov_ctrl.h similarity index 88% rename from src/cpu/x86_ops_mov_ctrl.h rename to src/cpu_common/x86_ops_mov_ctrl.h index becb0e095..06a89884b 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu_common/x86_ops_mov_ctrl.h @@ -2,7 +2,6 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from CRx\n"); x86gpf(NULL, 0); return 1; } @@ -27,7 +26,6 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) break; } default: - x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -40,7 +38,6 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from CRx\n"); x86gpf(NULL, 0); return 1; } @@ -65,7 +62,6 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) break; } default: - x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -79,7 +75,6 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from DRx\n"); x86gpf(NULL, 0); return 1; } @@ -93,7 +88,6 @@ static int opMOV_r_DRx_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from DRx\n"); x86gpf(NULL, 0); return 1; } @@ -110,7 +104,6 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load CRx\n"); x86gpf(NULL,0); return 1; } @@ -127,11 +120,11 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) mmu_perm=4; if (is486 && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; - else if (isibmcpu) - cpu_cache_int_enabled = 1; + else if (isibmcpu) + cpu_cache_int_enabled = 1; else - cpu_cache_int_enabled = 0; - if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); if (cr0 & 1) cpu_cur_status |= CPU_STATUS_PMODE; @@ -153,7 +146,6 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) } default: - x386_dynarec_log("Bad load CR%i\n", cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -168,7 +160,6 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load CRx\n"); x86gpf(NULL,0); return 1; } @@ -209,7 +200,6 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) } default: - x386_dynarec_log("Bad load CR%i\n", cpu_reg); cpu_state.pc = cpu_state.oldpc; x86illegal(); break; @@ -223,7 +213,6 @@ static int opMOV_DRx_r_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load DRx\n"); x86gpf(NULL, 0); return 1; } @@ -237,7 +226,6 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load DRx\n"); x86gpf(NULL, 0); return 1; } @@ -252,7 +240,6 @@ static int opMOV_r_TRx_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from TRx\n"); x86gpf(NULL, 0); return 1; } @@ -266,7 +253,6 @@ static int opMOV_r_TRx_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load from TRx\n"); x86gpf(NULL, 0); return 1; } @@ -281,7 +267,6 @@ static int opMOV_TRx_r_a16(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load TRx\n"); x86gpf(NULL, 0); return 1; } @@ -294,7 +279,6 @@ static int opMOV_TRx_r_a32(uint32_t fetchdat) { if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { - x386_dynarec_log("Can't load TRx\n"); x86gpf(NULL, 0); return 1; } diff --git a/src/cpu_new/x86_ops_mov_seg.h b/src/cpu_common/x86_ops_mov_seg.h similarity index 100% rename from src/cpu_new/x86_ops_mov_seg.h rename to src/cpu_common/x86_ops_mov_seg.h diff --git a/src/cpu_new/x86_ops_movx.h b/src/cpu_common/x86_ops_movx.h similarity index 100% rename from src/cpu_new/x86_ops_movx.h rename to src/cpu_common/x86_ops_movx.h diff --git a/src/cpu_new/x86_ops_msr.h b/src/cpu_common/x86_ops_msr.h similarity index 100% rename from src/cpu_new/x86_ops_msr.h rename to src/cpu_common/x86_ops_msr.h diff --git a/src/cpu_new/x86_ops_mul.h b/src/cpu_common/x86_ops_mul.h similarity index 96% rename from src/cpu_new/x86_ops_mul.h rename to src/cpu_common/x86_ops_mul.h index f3e10e5a0..a96ce54a2 100644 --- a/src/cpu_new/x86_ops_mul.h +++ b/src/cpu_common/x86_ops_mul.h @@ -6,7 +6,7 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getword(); if (cpu_state.abrt) return 1; @@ -28,7 +28,7 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getword(); if (cpu_state.abrt) return 1; @@ -51,7 +51,7 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getlong(); if (cpu_state.abrt) return 1; @@ -73,7 +73,7 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getlong(); if (cpu_state.abrt) return 1; @@ -96,7 +96,7 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getbyte(); if (cpu_state.abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; @@ -119,7 +119,7 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getbyte(); if (cpu_state.abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; @@ -142,8 +142,8 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getbyte(); if (cpu_state.abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; @@ -165,8 +165,8 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getbyte(); if (cpu_state.abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; @@ -209,8 +209,8 @@ static int opIMUL_w_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = templ & 0xFFFF; @@ -229,8 +229,8 @@ static int opIMUL_l_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; @@ -248,8 +248,8 @@ static int opIMUL_l_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu_common/x86_ops_pmode.h similarity index 94% rename from src/cpu/x86_ops_pmode.h rename to src/cpu_common/x86_ops_pmode.h index cdf89d98d..7fe5d4938 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu_common/x86_ops_pmode.h @@ -4,10 +4,8 @@ static int opARPL_a16(uint32_t fetchdat) NOTRM fetch_ea_16(fetchdat); - /* x386_dynarec_log("ARPL_a16\n"); */ if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - + SEG_CHECK_WRITE(cpu_state.ea_seg); temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -30,10 +28,8 @@ static int opARPL_a32(uint32_t fetchdat) NOTRM fetch_ea_32(fetchdat); - /* x386_dynarec_log("ARPL_a32\n"); */ if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - + SEG_CHECK_WRITE(cpu_state.ea_seg); temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -55,12 +51,12 @@ static int opARPL_a32(uint32_t fetchdat) static int opLAR_ ## name(uint32_t fetchdat) \ { \ int valid; \ - uint16_t sel, desc = 0; \ + uint16_t sel, desc = 0; \ \ NOTRM \ fetch_ea(fetchdat); \ if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ \ sel = geteaw(); if (cpu_state.abrt) return 1; \ \ @@ -107,7 +103,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1) static int opLSL_ ## name(uint32_t fetchdat) \ { \ int valid; \ - uint16_t sel, desc = 0; \ + uint16_t sel, desc = 0; \ \ NOTRM \ fetch_ea(fetchdat); \ @@ -169,7 +165,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) uint16_t desc, sel; uint8_t access; - /* x386_dynarec_log("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ switch (rmdat & 0x38) { case 0x00: /*SLDT*/ @@ -189,7 +184,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) case 0x10: /*LLDT*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LLDT!\n"); x86gpf(NULL,0); return 1; } @@ -217,7 +211,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) case 0x18: /*LTR*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LTR!\n"); x86gpf(NULL,0); break; } @@ -289,7 +282,6 @@ static int op0F00_common(uint32_t fetchdat, int ea32) break; default: - x386_dynarec_log("Bad 0F 00 opcode %02X\n", rmdat & 0x38); cpu_state.pc -= 3; x86illegal(); break; @@ -318,14 +310,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { uint32_t base; uint16_t limit, tempw; - /* x386_dynarec_log("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ switch (rmdat & 0x38) { case 0x00: /*SGDT*/ if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(gdt.limit); - base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */ + base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); if (is286) base |= 0xff000000; writememl(easeg, cpu_state.eaaddr + 2, base); @@ -346,16 +337,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x10: /*LGDT*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LGDT!\n"); x86gpf(NULL,0); break; } - /* x386_dynarec_log("LGDT %08X:%08X\n", easeg, eaaddr); */ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - /* x386_dynarec_log(" %08X %04X\n", base, limit); */ gdt.limit = limit; gdt.base = base; if (!is32) gdt.base &= 0xffffff; @@ -365,16 +353,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x18: /*LIDT*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid LIDT!\n"); x86gpf(NULL,0); break; } - /* x386_dynarec_log("LIDT %08X:%08X\n", easeg, eaaddr); */ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - /* x386_dynarec_log(" %08X %04X\n", base, limit); */ idt.limit = limit; idt.base = base; if (!is32) idt.base &= 0xffffff; @@ -394,7 +379,6 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x30: /*LMSW*/ if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1)) { - x386_dynarec_log("LMSW - ring not zero!\n"); x86gpf(NULL, 0); break; } @@ -421,11 +405,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { - x386_dynarec_log("Invalid INVLPG!\n"); x86gpf(NULL, 0); break; } - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); mmu_invalidate(ds + cpu_state.eaaddr); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); @@ -433,7 +416,6 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) } default: - x386_dynarec_log("Bad 0F 01 opcode %02X\n", rmdat & 0x38); cpu_state.pc -= 3; x86illegal(); break; diff --git a/src/cpu_new/x86_ops_prefix.h b/src/cpu_common/x86_ops_prefix.h similarity index 100% rename from src/cpu_new/x86_ops_prefix.h rename to src/cpu_common/x86_ops_prefix.h diff --git a/src/cpu_new/x86_ops_rep.h b/src/cpu_common/x86_ops_rep.h similarity index 100% rename from src/cpu_new/x86_ops_rep.h rename to src/cpu_common/x86_ops_rep.h diff --git a/src/cpu_new/x86_ops_ret.h b/src/cpu_common/x86_ops_ret.h similarity index 96% rename from src/cpu_new/x86_ops_ret.h rename to src/cpu_common/x86_ops_ret.h index 133c6153b..1ebe67b9c 100644 --- a/src/cpu_new/x86_ops_ret.h +++ b/src/cpu_common/x86_ops_ret.h @@ -1,9 +1,16 @@ +#ifdef USE_NEW_DYNAREC +#define CPU_SET_OXPC +#else +#define CPU_SET_OXPC oxpc = cpu_state.pc; +#endif + #define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(0, stack_offset); \ return 1; \ } \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmemw(ss, ESP); \ @@ -14,7 +21,7 @@ cpu_state.pc = readmemw(ss, SP); \ loadcs(readmemw(ss, SP + 2)); \ } \ - if (cpu_state.abrt) return 1; \ + if (cpu_state.abrt) return 1; \ if (stack32) ESP += 4 + stack_offset; \ else SP += 4 + stack_offset; \ cycles -= timing_retf_rm; @@ -25,6 +32,7 @@ pmoderetf(1, stack_offset); \ return 1; \ } \ + CPU_SET_OXPC \ if (stack32) \ { \ cpu_state.pc = readmeml(ss, ESP); \ @@ -106,6 +114,7 @@ static int opIRET_286(uint32_t fetchdat) else { uint16_t new_cs; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -172,7 +181,7 @@ static int opIRET(uint32_t fetchdat) } else { - if (msw&1) + if (msw&1) { optype = IRET; pmodeiret(0); @@ -181,6 +190,7 @@ static int opIRET(uint32_t fetchdat) else { uint16_t new_cs; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -226,6 +236,7 @@ static int opIRETD(uint32_t fetchdat) else { uint16_t new_cs; + CPU_SET_OXPC if (stack32) { cpu_state.pc = readmeml(ss, ESP); diff --git a/src/cpu_new/x86_ops_set.h b/src/cpu_common/x86_ops_set.h similarity index 100% rename from src/cpu_new/x86_ops_set.h rename to src/cpu_common/x86_ops_set.h diff --git a/src/cpu/x86_ops_stack.h b/src/cpu_common/x86_ops_stack.h similarity index 97% rename from src/cpu/x86_ops_stack.h rename to src/cpu_common/x86_ops_stack.h index 20b0aa766..9ca1171a0 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu_common/x86_ops_stack.h @@ -278,9 +278,9 @@ static int opPOPL_a16(uint32_t fetchdat) temp = POP_L(); if (cpu_state.abrt) return 1; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(temp); if (cpu_state.abrt) { @@ -470,17 +470,17 @@ static int opLEAVE_l(uint32_t fetchdat) } -PUSH_SEG_OPS(CS) -PUSH_SEG_OPS(DS) -PUSH_SEG_OPS(ES) -PUSH_SEG_OPS(FS) -PUSH_SEG_OPS(GS) -PUSH_SEG_OPS(SS) +PUSH_SEG_OPS(CS); +PUSH_SEG_OPS(DS); +PUSH_SEG_OPS(ES); +PUSH_SEG_OPS(FS); +PUSH_SEG_OPS(GS); +PUSH_SEG_OPS(SS); -POP_SEG_OPS(DS, &cpu_state.seg_ds) -POP_SEG_OPS(ES, &cpu_state.seg_es) -POP_SEG_OPS(FS, &cpu_state.seg_fs) -POP_SEG_OPS(GS, &cpu_state.seg_gs) +POP_SEG_OPS(DS, &cpu_state.seg_ds); +POP_SEG_OPS(ES, &cpu_state.seg_es); +POP_SEG_OPS(FS, &cpu_state.seg_fs); +POP_SEG_OPS(GS, &cpu_state.seg_gs); static int opPOP_SS_w(uint32_t fetchdat) @@ -488,7 +488,7 @@ static int opPOP_SS_w(uint32_t fetchdat) uint16_t temp_seg; uint32_t temp_esp = ESP; temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } CLOCK_CYCLES(is486 ? 3 : 7); PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); @@ -508,7 +508,7 @@ static int opPOP_SS_l(uint32_t fetchdat) uint32_t temp_seg; uint32_t temp_esp = ESP; temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } CLOCK_CYCLES(is486 ? 3 : 7); PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); diff --git a/src/cpu/x86_ops_string.h b/src/cpu_common/x86_ops_string.h similarity index 85% rename from src/cpu/x86_ops_string.h rename to src/cpu_common/x86_ops_string.h index 41e368cc7..c02725138 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu_common/x86_ops_string.h @@ -7,7 +7,7 @@ static int opMOVSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememb(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + else { DI++; SI++; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); return 0; @@ -21,7 +21,7 @@ static int opMOVSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememb(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } + else { EDI++; ESI++; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); return 0; @@ -36,7 +36,7 @@ static int opMOVSW_a16(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememw(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } + else { DI += 2; SI += 2; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); return 0; @@ -50,7 +50,7 @@ static int opMOVSW_a32(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememw(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } + else { EDI += 2; ESI += 2; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); return 0; @@ -65,7 +65,7 @@ static int opMOVSL_a16(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememl(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } + else { DI += 4; SI += 4; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); return 0; @@ -79,7 +79,7 @@ static int opMOVSL_a32(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememl(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } + else { EDI += 4; ESI += 4; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); return 0; @@ -96,7 +96,7 @@ static int opCMPSB_a16(uint32_t fetchdat) dst = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + else { DI++; SI++; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); return 0; @@ -111,7 +111,7 @@ static int opCMPSB_a32(uint32_t fetchdat) dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(src, dst); if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } + else { EDI++; ESI++; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); return 0; @@ -127,7 +127,7 @@ static int opCMPSW_a16(uint32_t fetchdat) dst = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } + else { DI += 2; SI += 2; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); return 0; @@ -142,7 +142,7 @@ static int opCMPSW_a32(uint32_t fetchdat) dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } + else { EDI += 2; ESI += 2; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); return 0; @@ -158,7 +158,7 @@ static int opCMPSL_a16(uint32_t fetchdat) dst = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } + else { DI += 4; SI += 4; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0); return 0; @@ -173,7 +173,7 @@ static int opCMPSL_a32(uint32_t fetchdat) dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(src, dst); if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } + else { EDI += 4; ESI += 4; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1); return 0; @@ -181,20 +181,20 @@ static int opCMPSL_a32(uint32_t fetchdat) static int opSTOSB_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, DI, AL); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI--; - else DI++; + else DI++; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return 0; } static int opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, EDI, AL); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; + else EDI++; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); return 0; @@ -202,20 +202,20 @@ static int opSTOSB_a32(uint32_t fetchdat) static int opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, DI, AX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; + else DI += 2; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return 0; } static int opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, EDI, AX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; + else EDI += 2; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); return 0; @@ -223,20 +223,20 @@ static int opSTOSW_a32(uint32_t fetchdat) static int opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, DI, EAX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; + else DI += 4; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); return 0; } static int opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; + else EDI += 4; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); return 0; @@ -251,7 +251,7 @@ static int opLODSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AL = temp; if (cpu_state.flags & D_FLAG) SI--; - else SI++; + else SI++; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); return 0; @@ -264,7 +264,7 @@ static int opLODSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AL = temp; if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; + else ESI++; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); return 0; @@ -278,7 +278,7 @@ static int opLODSW_a16(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AX = temp; if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; + else SI += 2; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); return 0; @@ -291,7 +291,7 @@ static int opLODSW_a32(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AX = temp; if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; + else ESI += 2; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); return 0; @@ -305,7 +305,7 @@ static int opLODSL_a16(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; EAX = temp; if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; + else SI += 4; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); return 0; @@ -318,7 +318,7 @@ static int opLODSL_a32(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; EAX = temp; if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; + else ESI += 4; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); return 0; @@ -333,7 +333,7 @@ static int opSCASB_a16(uint32_t fetchdat) temp = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (cpu_state.flags & D_FLAG) DI--; - else DI++; + else DI++; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); return 0; @@ -346,7 +346,7 @@ static int opSCASB_a32(uint32_t fetchdat) temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; + else EDI++; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); return 0; @@ -360,7 +360,7 @@ static int opSCASW_a16(uint32_t fetchdat) temp = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; + else DI += 2; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); return 0; @@ -373,7 +373,7 @@ static int opSCASW_a32(uint32_t fetchdat) temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; + else EDI += 2; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); return 0; @@ -387,7 +387,7 @@ static int opSCASL_a16(uint32_t fetchdat) temp = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; + else DI += 4; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); return 0; @@ -400,7 +400,7 @@ static int opSCASL_a32(uint32_t fetchdat) temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; + else EDI += 4; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); return 0; @@ -409,13 +409,13 @@ static int opSCASL_a32(uint32_t fetchdat) static int opINSB_a16(uint32_t fetchdat) { uint8_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); temp = inb(DX); writememb(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI--; - else DI++; + else DI++; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); return 0; @@ -423,13 +423,13 @@ static int opINSB_a16(uint32_t fetchdat) static int opINSB_a32(uint32_t fetchdat) { uint8_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); temp = inb(DX); writememb(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; + else EDI++; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); return 0; @@ -438,14 +438,14 @@ static int opINSB_a32(uint32_t fetchdat) static int opINSW_a16(uint32_t fetchdat) { uint16_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); writememw(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; + else DI += 2; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); return 0; @@ -453,14 +453,14 @@ static int opINSW_a16(uint32_t fetchdat) static int opINSW_a32(uint32_t fetchdat) { uint16_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); writememw(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; + else EDI += 2; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); return 0; @@ -469,8 +469,8 @@ static int opINSW_a32(uint32_t fetchdat) static int opINSL_a16(uint32_t fetchdat) { uint32_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -478,7 +478,7 @@ static int opINSL_a16(uint32_t fetchdat) temp = inl(DX); writememl(es, DI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; + else DI += 4; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); return 0; @@ -486,8 +486,8 @@ static int opINSL_a16(uint32_t fetchdat) static int opINSL_a32(uint32_t fetchdat) { uint32_t temp; - - SEG_CHECK_WRITE(&cpu_state.seg_es); + + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -495,7 +495,7 @@ static int opINSL_a32(uint32_t fetchdat) temp = inl(DX); writememl(es, EDI, temp); if (cpu_state.abrt) return 1; if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; + else EDI += 4; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); return 0; @@ -509,7 +509,7 @@ static int opOUTSB_a16(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); if (cpu_state.flags & D_FLAG) SI--; - else SI++; + else SI++; outb(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); @@ -523,7 +523,7 @@ static int opOUTSB_a32(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; + else ESI++; outb(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); @@ -539,7 +539,7 @@ static int opOUTSW_a16(uint32_t fetchdat) check_io_perm(DX); check_io_perm(DX + 1); if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; + else SI += 2; outw(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); @@ -554,7 +554,7 @@ static int opOUTSW_a32(uint32_t fetchdat) check_io_perm(DX); check_io_perm(DX + 1); if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; + else ESI += 2; outw(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); @@ -572,7 +572,7 @@ static int opOUTSL_a16(uint32_t fetchdat) check_io_perm(DX + 2); check_io_perm(DX + 3); if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; + else SI += 4; outl(EDX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); @@ -589,7 +589,7 @@ static int opOUTSL_a32(uint32_t fetchdat) check_io_perm(DX + 2); check_io_perm(DX + 3); if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; + else ESI += 4; outl(EDX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu_common/x86_ops_xchg.h similarity index 99% rename from src/cpu/x86_ops_xchg.h rename to src/cpu_common/x86_ops_xchg.h index 3880f70e7..6a787273e 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu_common/x86_ops_xchg.h @@ -1,6 +1,7 @@ static int opXCHG_b_a16(uint32_t fetchdat) { uint8_t temp; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -14,6 +15,7 @@ static int opXCHG_b_a16(uint32_t fetchdat) static int opXCHG_b_a32(uint32_t fetchdat) { uint8_t temp; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -28,6 +30,7 @@ static int opXCHG_b_a32(uint32_t fetchdat) static int opXCHG_w_a16(uint32_t fetchdat) { uint16_t temp; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -41,6 +44,7 @@ static int opXCHG_w_a16(uint32_t fetchdat) static int opXCHG_w_a32(uint32_t fetchdat) { uint16_t temp; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -55,6 +59,7 @@ static int opXCHG_w_a32(uint32_t fetchdat) static int opXCHG_l_a16(uint32_t fetchdat) { uint32_t temp; + fetch_ea_16(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -68,6 +73,7 @@ static int opXCHG_l_a16(uint32_t fetchdat) static int opXCHG_l_a32(uint32_t fetchdat) { uint32_t temp; + fetch_ea_32(fetchdat); if (cpu_mod != 3) SEG_CHECK_WRITE(cpu_state.ea_seg); diff --git a/src/cpu_new/x86seg.h b/src/cpu_common/x86seg.h similarity index 100% rename from src/cpu_new/x86seg.h rename to src/cpu_common/x86seg.h diff --git a/src/cpu/x87.c b/src/cpu_common/x87.c similarity index 64% rename from src/cpu/x87.c rename to src/cpu_common/x87.c index 5016661a3..8a5363cd8 100644 --- a/src/cpu/x87.c +++ b/src/cpu_common/x87.c @@ -6,10 +6,10 @@ #define fplog 0 #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" -#include "../pic.h" +#include "mem.h" +#include "pic.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" @@ -37,6 +37,49 @@ fpu_log(const char *fmt, ...) #endif +#ifdef USE_NEW_DYNAREC +#define X87_TAG_VALID 0 +#define X87_TAG_ZERO 1 +#define X87_TAG_INVALID 2 +#define X87_TAG_EMPTY 3 + +uint16_t x87_gettag() +{ + uint16_t ret = 0; + int c; + + for (c = 0; c < 8; c++) + { + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c*2); + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) + ret |= X87_TAG_ZERO << (c * 2); + else + ret |= X87_TAG_VALID << (c * 2); + } + + return ret; +} + +void x87_settag(uint16_t new_tag) +{ + int c; + + for (c = 0; c < 8; c++) + { + int tag = (new_tag >> (c * 2)) & 3; + + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } +} +#else uint16_t x87_gettag() { uint16_t ret = 0; @@ -64,6 +107,7 @@ void x87_settag(uint16_t new_tag) cpu_state.tag[6] = (new_tag >> 12) & 3; cpu_state.tag[7] = (new_tag >> 14) & 3; } +#endif #ifdef ENABLE_808X_LOG diff --git a/src/cpu_common/x87.h b/src/cpu_common/x87.h new file mode 100644 index 000000000..be30c280c --- /dev/null +++ b/src/cpu_common/x87.h @@ -0,0 +1,58 @@ +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + +uint32_t x87_pc_off,x87_op_off; +uint16_t x87_pc_seg,x87_op_seg; + +static inline void x87_set_mmx() +{ +#ifdef USE_NEW_DYNAREC + cpu_state.TOP = 0; + *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; + cpu_state.ismmx = 1; +#else + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 1; +#endif +} + +static inline void x87_emms() +{ +#ifdef USE_NEW_DYNAREC + *(uint64_t *)cpu_state.tag = 0; + cpu_state.ismmx = 0; +#else + uint64_t *p; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; +#endif +} + + +uint16_t x87_gettag(); +void x87_settag(uint16_t new_tag); + +#ifdef USE_NEW_DYNAREC +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 7) + +#define X87_ROUNDING_NEAREST 0 +#define X87_ROUNDING_DOWN 1 +#define X87_ROUNDING_UP 2 +#define X87_ROUNDING_CHOP 3 + +void codegen_set_rounding_mode(int mode); +#else +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 2) +#endif diff --git a/src/cpu/x87_ops.h b/src/cpu_common/x87_ops.h similarity index 97% rename from src/cpu/x87_ops.h rename to src/cpu_common/x87_ops.h index bf54afa40..239b449f2 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu_common/x87_ops.h @@ -25,6 +25,7 @@ #ifdef _MSC_VER # include #endif +// #include "x87_timings.h" #ifdef ENABLE_FPU_LOG extern void fpu_log(const char *fmt, ...); @@ -38,11 +39,6 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ #define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - #define STATUS_ZERODIVIDE 4 #ifdef FPU_8087 @@ -92,12 +88,18 @@ static __inline void x87_checkexceptions() static __inline void x87_push(double i) { +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else cpu_state.TOP=(cpu_state.TOP-1)&7; cpu_state.ST[cpu_state.TOP] = i; cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; +#endif } -static inline void x87_push_u64(uint64_t i) +static __inline void x87_push_u64(uint64_t i) { union { @@ -107,26 +109,62 @@ static inline void x87_push_u64(uint64_t i) td.ll = i; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else cpu_state.TOP=(cpu_state.TOP-1)&7; cpu_state.ST[cpu_state.TOP] = td.d; cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; +#endif } static __inline double x87_pop() { +#ifdef USE_NEW_DYNAREC + double t = cpu_state.ST[cpu_state.TOP&7]; + cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + cpu_state.TOP++; + return t; +#else double t = cpu_state.ST[cpu_state.TOP]; cpu_state.tag[cpu_state.TOP&7] = 3; cpu_state.TOP=(cpu_state.TOP+1)&7; return t; +#endif } +static int old_round = FE_TONEAREST; + +static __inline void x87_round_save(void) +{ + old_round = fegetround(); +} + +static __inline void x87_round_set(void) +{ + old_round = fegetround(); + + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); +} + +static __inline void x87_round_restore(void) +{ + fesetround(old_round); +} + +#ifdef PCEM_CODE static __inline int64_t x87_fround(double b) { +#ifdef PCEM_CODE int64_t a, c; +#endif - switch ((cpu_state.npxc>>10)&3) + switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ +#ifdef PCEM_CODE a = (int64_t)floor(b); c = (int64_t)floor(b + 1.0); if ((b - a) < (c - b)) @@ -135,16 +173,35 @@ static __inline int64_t x87_fround(double b) return c; else return (a & 1) ? c : a; +#else + return (int64_t)round(b); +#endif case 1: /*Down*/ return (int64_t)floor(b); case 2: /*Up*/ return (int64_t)ceil(b); case 3: /*Chop*/ +#ifdef PCEM_CODE return (int64_t)b; - default: - return (int64_t)0; +#else + return (int64_t)trunc(b); +#endif } + + return 0; } +#else +static __inline int64_t x87_fround(double b) +{ + int64_t ret; + + x87_round_set(); + ret = (int64_t) rint(b); + x87_round_restore(); + + return ret; +} +#endif #define BIAS80 16383 #define BIAS64 1023 @@ -155,6 +212,7 @@ static __inline double x87_ld80() int64_t exp64final; int64_t mant64; int64_t sign; + struct { int16_t begin; union @@ -163,6 +221,7 @@ static __inline double x87_ld80() uint64_t ll; } eind; } test; + test.eind.ll = readmeml(easeg,cpu_state.eaaddr); test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; test.begin = readmemw(easeg,cpu_state.eaaddr+8); @@ -251,6 +310,17 @@ static __inline void x87_ld_frstor(int reg) cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); +#ifdef USE_NEW_DYNAREC + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + { + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } + else + { + cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.ST[reg] = x87_ld80(); + } +#else if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) { cpu_state.tag[reg] = TAG_UINT64; @@ -258,6 +328,7 @@ static __inline void x87_ld_frstor(int reg) } else cpu_state.ST[reg] = x87_ld80(); +#endif } static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) @@ -338,7 +409,7 @@ static __inline uint16_t x87_compare(double a, double b) #endif } -static inline uint16_t x87_ucompare(double a, double b) +static __inline uint16_t x87_ucompare(double a, double b) { #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ uint32_t result; @@ -412,6 +483,55 @@ typedef union } while (0) #endif +// #ifdef USE_NEW_DYNAREC +#if 1 +#define FP_TAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP&7].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP&7].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; +#ifdef USE_NEW_DYNAREC +#define FP_NNPXC() codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#else +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#endif +#define FP_TOP(x) (x & 7) +#define FP_DTAG 0ULL +#define FP_CTAG 0x0101010101010101ull +#define FP_EMPTY TAG_EMPTY +#ifdef USE_NEW_DYNAREC +#define FP_RNPXC() codegen_set_rounding_mode(X87_ROUNDING_NEAREST); +#else +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#endif +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_DECTOP() cpu_state.TOP--; +#define FP_INCTOP() cpu_state.TOP++; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#define FP_686 +#endif +#else +#define FP_TAG() cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#define FP_TOP(x) (x) +#define FP_DTAG 0x0303030303030303ll +#define FP_CTAG 0ULL +#define FP_EMPTY 3 +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = 1; +#define FP_DECTOP() cpu_state.TOP = (cpu_state.TOP - 1) & 7 +#define FP_INCTOP() cpu_state.TOP = (cpu_state.TOP + 1) & 7 +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#define FP_686 +#endif +#endif + #include "x87_ops_arith.h" #include "x87_ops_misc.h" #include "x87_ops_loadstore.h" @@ -1050,7 +1170,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) const OpFn OP_TABLE(fpu_686_da_a16)[256] = { opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, @@ -1283,7 +1403,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) const OpFn OP_TABLE(fpu_686_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, @@ -1856,7 +1976,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) const OpFn OP_TABLE(fpu_686_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, diff --git a/src/cpu_common/x87_ops_arith.h b/src/cpu_common/x87_ops_arith.h new file mode 100644 index 000000000..e90761ca1 --- /dev/null +++ b/src/cpu_common/x87_ops_arith.h @@ -0,0 +1,435 @@ +#define opFPU(name, optype, a_size, load_var, get, use_var) \ +static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) += use_var; \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(8); \ + return 0; \ +} \ +static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + cpu_state.npxs &= ~(C0|C2|C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ + CLOCK_CYCLES(4); \ + return 0; \ +} \ +static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + cpu_state.npxs &= ~(C0|C2|C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ + x87_pop(); \ + CLOCK_CYCLES(4); \ + return 0; \ +} \ +static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + x87_div(ST(0), ST(0), use_var); \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(73); \ + return 0; \ +} \ +static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + x87_div(ST(0), use_var, ST(0)); \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(73); \ + return 0; \ +} \ +static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) *= use_var; \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(11); \ + return 0; \ +} \ +static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) -= use_var; \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(8); \ + return 0; \ +} \ +static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ +{ \ + optype t; \ + FP_ENTER(); \ + fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); if (cpu_state.abrt) return 1; \ + x87_round_set(); \ + ST(0) = use_var - ST(0); \ + x87_round_restore(); \ + FP_TAG(); \ + CLOCK_CYCLES(8); \ + return 0; \ +} + + +opFPU(s, x87_ts, 16, t.i, geteal, t.s) +#ifndef FPU_8087 +opFPU(s, x87_ts, 32, t.i, geteal, t.s) +#endif +opFPU(d, x87_td, 16, t.i, geteaq, t.d) +#ifndef FPU_8087 +opFPU(d, x87_td, 32, t.i, geteaq, t.d) +#endif + +opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t) +#ifndef FPU_8087 +opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t) +#endif +opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t) +#ifndef FPU_8087 +opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t) +#endif + + + + +static int opFADD(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) + ST(fetchdat & 7); + FP_TAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFADDr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_FTAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFADDP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} + +static int opFCOM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; + CLOCK_CYCLES(4); + return 0; +} + +static int opFCOMP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} + +static int opFCOMPP(uint32_t fetchdat) +{ + uint64_t *p, *q; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + p = (uint64_t *)&ST(0); + q = (uint64_t *)&ST(1); + if ((*p == ((uint64_t)1 << 63) && *q == 0) && is386) + cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ + else + cpu_state.npxs |= x87_compare(ST(0), ST(1)); + + x87_pop(); + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} +#ifndef FPU_8087 +static int opFUCOMPP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); + x87_pop(); + x87_pop(); + CLOCK_CYCLES(5); + return 0; +} + +#ifdef FP_686 +static int opFCOMI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(4); + return 0; +} +static int opFCOMIP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} +#endif +#endif + +static int opFDIV(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(0), ST(fetchdat & 7)); + FP_TAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_FTAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(73); + return 0; +} + +static int opFDIVR(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(fetchdat&7), ST(0)); + FP_TAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVRr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_FTAG(); + CLOCK_CYCLES(73); + return 0; +} +static int opFDIVRP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(73); + return 0; +} + +static int opFMUL(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) * ST(fetchdat & 7); + FP_TAG(); + CLOCK_CYCLES(16); + return 0; +} +static int opFMULr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_FTAG(); + CLOCK_CYCLES(16); + return 0; +} +static int opFMULP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(16); + return 0; +} + +static int opFSUB(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) - ST(fetchdat & 7); + FP_TAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_FTAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} + +static int opFSUBR(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(fetchdat & 7) - ST(0); + FP_TAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBRr(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_FTAG(); + CLOCK_CYCLES(8); + return 0; +} +static int opFSUBRP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_FTAG(); + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} + +#ifndef FPU_8087 +static int opFUCOM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + CLOCK_CYCLES(4); + return 0; +} + +static int opFUCOMP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} + +#ifdef FP_686 +static int opFUCOMI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(4); + return 0; +} +static int opFUCOMIP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES(4); + return 0; +} +#endif +#endif diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu_common/x87_ops_loadstore.h similarity index 97% rename from src/cpu/x87_ops_loadstore.h rename to src/cpu_common/x87_ops_loadstore.h index 3001e8ca8..b5ad491f9 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu_common/x87_ops_loadstore.h @@ -101,8 +101,8 @@ static int opFILDiq_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp64 = geteaq(); if (cpu_state.abrt) return 1; x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; + FP_LSQ(); + FP_LSTAG(); CLOCK_CYCLES(10); return 0; @@ -116,8 +116,8 @@ static int opFILDiq_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp64 = geteaq(); if (cpu_state.abrt) return 1; x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; + FP_LSQ(); + FP_LSTAG(); CLOCK_CYCLES(10); return 0; @@ -186,7 +186,7 @@ static int FISTPiq_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; + FP_LSRETQ() else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; @@ -202,7 +202,7 @@ static int FISTPiq_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; + FP_LSRETQ() else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; diff --git a/src/cpu/x87_ops_misc.h b/src/cpu_common/x87_ops_misc.h similarity index 88% rename from src/cpu/x87_ops_misc.h rename to src/cpu_common/x87_ops_misc.h index 36dbd8a76..406c6c86d 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu_common/x87_ops_misc.h @@ -21,7 +21,6 @@ static int opFSTSW_AX(uint32_t fetchdat) #endif - static int opFNOP(uint32_t fetchdat) { FP_ENTER(); @@ -49,10 +48,10 @@ static int opFINIT(uint32_t fetchdat) #else cpu_state.npxc = 0x37F; #endif - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + FP_RNPXC(); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; + *p = FP_DTAG; cpu_state.TOP = 0; cpu_state.ismmx = 0; CLOCK_CYCLES(17); @@ -65,7 +64,7 @@ static int opFFREE(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; CLOCK_CYCLES(3); return 0; } @@ -74,7 +73,7 @@ static int opFFREEP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(3); return 0; @@ -113,7 +112,7 @@ static int FSTOR() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -122,7 +121,7 @@ static int FSTOR() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -144,7 +143,7 @@ static int FSTOR() p = (uint64_t *)cpu_state.tag; if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) + !cpu_state.TOP && (*p == FP_CTAG)) cpu_state.ismmx = 1; CLOCK_CYCLES((cr0 & 1) ? 34 : 44); @@ -154,7 +153,7 @@ static int opFSTOR_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); FSTOR(); return cpu_state.abrt; } @@ -163,7 +162,7 @@ static int opFSTOR_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); FSTOR(); return cpu_state.abrt; } @@ -174,7 +173,7 @@ static int FSAVE() uint64_t *p; FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (FP_TOP(cpu_state.TOP) << 11); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { @@ -306,10 +305,10 @@ static int FSAVE() } cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + FP_RNPXC(); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; - *p = 0x0303030303030303ll; + *p = FP_DTAG; cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -320,7 +319,7 @@ static int opFSAVE_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSAVE(); return cpu_state.abrt; } @@ -329,7 +328,7 @@ static int opFSAVE_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSAVE(); return cpu_state.abrt; } @@ -339,8 +338,8 @@ static int opFSTSW_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -349,8 +348,8 @@ static int opFSTSW_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -367,8 +366,8 @@ static int opFLD(uint32_t fetchdat) old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; x87_push(ST(fetchdat&7)); - cpu_state.tag[cpu_state.TOP] = old_tag; - cpu_state.MM[cpu_state.TOP].q = old_i64; + cpu_state.tag[FP_TOP(cpu_state.TOP)] = old_tag; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = old_i64; CLOCK_CYCLES(4); return 0; } @@ -383,11 +382,11 @@ static int opFXCH(uint32_t fetchdat) td = ST(0); ST(0) = ST(fetchdat&7); ST(fetchdat&7) = td; - old_tag = cpu_state.tag[cpu_state.TOP]; - cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_tag = cpu_state.tag[FP_TOP(cpu_state.TOP)]; + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[cpu_state.TOP].q; - cpu_state.MM[cpu_state.TOP].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + old_i64 = cpu_state.MM[FP_TOP(cpu_state.TOP)].q; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; CLOCK_CYCLES(4); @@ -399,7 +398,7 @@ static int opFCHS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = -ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(6); return 0; } @@ -409,7 +408,7 @@ static int opFABS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = fabs(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(3); return 0; } @@ -430,7 +429,7 @@ static int opFXAM(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= ~(C0|C1|C2|C3); - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); + if (cpu_state.tag[cpu_state.TOP&7] == FP_EMPTY) cpu_state.npxs |= (C0|C3); else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; @@ -497,7 +496,7 @@ static int opFLDZ(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(0.0); - cpu_state.tag[cpu_state.TOP&7] = 1; + FP_ZTAG(); CLOCK_CYCLES(4); return 0; } @@ -507,7 +506,7 @@ static int opF2XM1(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = pow(2.0, ST(0)) - 1.0; - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(200); return 0; } @@ -517,7 +516,7 @@ static int opFYL2X(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + FP_NTAG(); x87_pop(); CLOCK_CYCLES(250); return 0; @@ -527,8 +526,8 @@ static int opFYL2XP1(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); + FP_NTAG(); x87_pop(); CLOCK_CYCLES(250); return 0; @@ -539,7 +538,7 @@ static int opFPTAN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = tan(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); x87_push(1.0); cpu_state.npxs &= ~C2; CLOCK_CYCLES(235); @@ -551,7 +550,7 @@ static int opFPATAN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(1) = atan2(ST(1), ST(0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + FP_NTAG(); x87_pop(); CLOCK_CYCLES(250); return 0; @@ -561,7 +560,7 @@ static int opFDECSTP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.TOP = (cpu_state.TOP - 1) & 7; + FP_DECTOP(); CLOCK_CYCLES(4); return 0; } @@ -570,7 +569,7 @@ static int opFINCSTP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.TOP = (cpu_state.TOP + 1) & 7; + FP_INCTOP(); CLOCK_CYCLES(4); return 0; } @@ -582,7 +581,7 @@ static int opFPREM(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; @@ -598,7 +597,7 @@ static int opFPREM1(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; @@ -613,7 +612,7 @@ static int opFSQRT(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = sqrt(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(83); return 0; } @@ -626,7 +625,7 @@ static int opFSINCOS(uint32_t fetchdat) cpu_state.pc++; td = ST(0); ST(0) = sin(td); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); x87_push(cos(td)); cpu_state.npxs &= ~C2; CLOCK_CYCLES(330); @@ -636,10 +635,18 @@ static int opFSINCOS(uint32_t fetchdat) static int opFRNDINT(uint32_t fetchdat) { + double rounded; FP_ENTER(); cpu_state.pc++; - ST(0) = (double)x87_fround(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + rounded = (double) x87_fround(ST(0)); +#ifndef PCEM_CODE + if (rounded > ST(0)) + cpu_state.npxs |= C1; + else + cpu_state.npxs &= ~C1; +#endif + ST(0) = rounded; + FP_TAG(); CLOCK_CYCLES(21); return 0; } @@ -651,7 +658,7 @@ static int opFSCALE(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(30); return 0; } @@ -662,7 +669,7 @@ static int opFSIN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = sin(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -673,7 +680,7 @@ static int opFCOS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = cos(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -689,7 +696,7 @@ static int FLDENV() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -697,7 +704,7 @@ static int FLDENV() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -735,7 +742,7 @@ static int opFLDCW_a16(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); CLOCK_CYCLES(4); return 0; } @@ -749,7 +756,7 @@ static int opFLDCW_a32(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + FP_NNPXC(); CLOCK_CYCLES(4); return 0; } @@ -839,7 +846,7 @@ static int opFSTCW_a32(uint32_t fetchdat) #endif #ifndef FPU_8087 -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#ifdef FP_686 #define opFCMOV(condition) \ static int opFCMOV ## condition(uint32_t fetchdat) \ { \ @@ -847,8 +854,8 @@ static int opFSTCW_a32(uint32_t fetchdat) cpu_state.pc++; \ if (cond_ ## condition) \ { \ - cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ ST(0) = ST(fetchdat & 7); \ } \ CLOCK_CYCLES(4); \ diff --git a/src/cpu_new/386.c b/src/cpu_new/386.c deleted file mode 100644 index 2b2268920..000000000 --- a/src/cpu_new/386.c +++ /dev/null @@ -1,303 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#ifndef INFINITY -# define INFINITY (__builtin_inff()) -#endif -#define HAVE_STDARG_H -#include "../86box.h" -#include "cpu.h" -#include "../timer.h" -#include "x86.h" -#include "x87.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pic.h" -#include "../pit.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "386_common.h" -#include "codegen.h" - - -#ifdef ENABLE_386_LOG -int x386_do_log = ENABLE_386_LOG; - - -void -x386_log(const char *fmt, ...) -{ - va_list ap; - - if (x386_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define x386_log(fmt, ...) -#endif - - -#undef CPU_BLOCK_END -#define CPU_BLOCK_END() - - -extern int codegen_flags_changed; - -int tempc, oldcpl, optype, inttype, oddeven = 0; -int timetolive; - -uint16_t oldcs; - -uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; -uint32_t oxpc; -uint32_t rmdat32; -uint32_t backupregs[16]; - -x86seg _oldds; - - -static __inline void -fetch_ea_32_long(uint32_t rmdat) -{ - uint8_t sib; - uint32_t addr; - - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) { - sib = rmdat >> 8; - - switch (cpu_mod) { - case 0: - cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1: - cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; - break; - case 2: - cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } else { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) { - if (cpu_rm == 5 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } else - cpu_state.eaaddr += getlong(); - } else if (cpu_rm == 5) - cpu_state.eaaddr = getlong(); - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } -} - - -static __inline void -fetch_ea_16_long(uint32_t rmdat) -{ - uint32_t addr; - - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) - cpu_state.eaaddr = getword(); - else { - switch (cpu_mod) { - case 0: - cpu_state.eaaddr = 0; - break; - case 1: - cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; - break; - case 2: - cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } -} - - -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 - -#include "x86_flags.h" - -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 - - -#define OP_TABLE(name) ops_ ## name - -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - -#include "x86_ops.h" - - -void -exec386(int cycs) -{ - uint8_t opcode; - int vector, tempi, cycdiff, oldcyc; - int cycle_period, ins_cycles; - uint32_t addr; - - cycles += cycs; - - while (cycles > 0) { - cycle_period = (timer_target - (uint32_t)tsc) + 1; - - x86_was_reset = 0; - cycdiff = 0; - oldcyc = cycles; - while (cycdiff < cycle_period) { - ins_cycles = cycles; - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } - - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_LOG - x386_log("Triple fault - reset\n"); -#endif - } - } - } - - ins_cycles -= cycles; - tsc += ins_cycles; - - cycdiff = oldcyc - cycles; - - if (trap) { - flags_rebuild(); - if (msw&1) - pmodeint(1,0); - else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } else if (nmi && nmi_enable && nmi_mask) { - cpu_state.oldpc = cpu_state.pc; - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } - } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { - vector = picinterrupt(); - if (vector != 0xFF) { - flags_rebuild(); - if (msw & 1) - pmodeint(vector, 0); - else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (vector << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } - } - - ins++; - - if (timetolive) { - timetolive--; - if (!timetolive) - fatal("Life expired\n"); - } - } - - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process(); - } -} diff --git a/src/cpu_new/codegen.c b/src/cpu_new/codegen.c index 243f61791..9758788b1 100644 --- a/src/cpu_new/codegen.c +++ b/src/cpu_new/codegen.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86_ops.h" #include "codegen.h" diff --git a/src/cpu_new/codegen.h b/src/cpu_new/codegen.h index d4f2563f6..039a34c0f 100644 --- a/src/cpu_new/codegen.h +++ b/src/cpu_new/codegen.h @@ -2,7 +2,7 @@ #define _CODEGEN_H_ #include "mem.h" -#include "x86_ops.h" +#include "../cpu_common/x86_ops.h" /*Handling self-modifying code (of which there is a lot on x86) : diff --git a/src/cpu_new/codegen_accumulate.c b/src/cpu_new/codegen_accumulate.c index c9b85ba78..726f5258f 100644 --- a/src/cpu_new/codegen_accumulate.c +++ b/src/cpu_new/codegen_accumulate.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/cpu_new/codegen_allocator.c b/src/cpu_new/codegen_allocator.c index b78c4df12..9f5d87852 100644 --- a/src/cpu_new/codegen_allocator.c +++ b/src/cpu_new/codegen_allocator.c @@ -9,9 +9,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm.c b/src/cpu_new/codegen_backend_arm.c index ddabbb5c5..8ad2d0011 100644 --- a/src/cpu_new/codegen_backend_arm.c +++ b/src/cpu_new/codegen_backend_arm.c @@ -2,9 +2,9 @@ #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm64.c b/src/cpu_new/codegen_backend_arm64.c index 32489000f..1cfd27d9e 100644 --- a/src/cpu_new/codegen_backend_arm64.c +++ b/src/cpu_new/codegen_backend_arm64.c @@ -2,9 +2,9 @@ #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm64_ops.c b/src/cpu_new/codegen_backend_arm64_ops.c index 44cf87647..f55b0d569 100644 --- a/src/cpu_new/codegen_backend_arm64_ops.c +++ b/src/cpu_new/codegen_backend_arm64_ops.c @@ -1,9 +1,9 @@ #ifdef __aarch64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm64_uops.c b/src/cpu_new/codegen_backend_arm64_uops.c index e9cf28684..b7cf12023 100644 --- a/src/cpu_new/codegen_backend_arm64_uops.c +++ b/src/cpu_new/codegen_backend_arm64_uops.c @@ -1,9 +1,9 @@ #ifdef __aarch64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x87.h" diff --git a/src/cpu_new/codegen_backend_arm_ops.c b/src/cpu_new/codegen_backend_arm_ops.c index 1b2ef28f3..4bb86c2e7 100644 --- a/src/cpu_new/codegen_backend_arm_ops.c +++ b/src/cpu_new/codegen_backend_arm_ops.c @@ -1,9 +1,9 @@ #ifdef __ARM_EABI__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_arm_uops.c b/src/cpu_new/codegen_backend_arm_uops.c index 1dbaab407..0ef7ed7eb 100644 --- a/src/cpu_new/codegen_backend_arm_uops.c +++ b/src/cpu_new/codegen_backend_arm_uops.c @@ -2,9 +2,9 @@ #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x87.h" diff --git a/src/cpu_new/codegen_backend_x86-64.c b/src/cpu_new/codegen_backend_x86-64.c index 4615aa381..d93fce248 100644 --- a/src/cpu_new/codegen_backend_x86-64.c +++ b/src/cpu_new/codegen_backend_x86-64.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86-64_ops.c b/src/cpu_new/codegen_backend_x86-64_ops.c index 8bb91da1c..dc1718892 100644 --- a/src/cpu_new/codegen_backend_x86-64_ops.c +++ b/src/cpu_new/codegen_backend_x86-64_ops.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86-64_ops_sse.c b/src/cpu_new/codegen_backend_x86-64_ops_sse.c index b8177648e..3a74910f2 100644 --- a/src/cpu_new/codegen_backend_x86-64_ops_sse.c +++ b/src/cpu_new/codegen_backend_x86-64_ops_sse.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86-64_uops.c b/src/cpu_new/codegen_backend_x86-64_uops.c index bff4e3775..f497aa569 100644 --- a/src/cpu_new/codegen_backend_x86-64_uops.c +++ b/src/cpu_new/codegen_backend_x86-64_uops.c @@ -1,9 +1,9 @@ #ifdef __amd64__ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x87.h" diff --git a/src/cpu_new/codegen_backend_x86.c b/src/cpu_new/codegen_backend_x86.c index d83d99af0..d364b7634 100644 --- a/src/cpu_new/codegen_backend_x86.c +++ b/src/cpu_new/codegen_backend_x86.c @@ -3,9 +3,9 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_ops.c b/src/cpu_new/codegen_backend_x86_ops.c index f5010e356..766ce0fc6 100644 --- a/src/cpu_new/codegen_backend_x86_ops.c +++ b/src/cpu_new/codegen_backend_x86_ops.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_ops_fpu.c b/src/cpu_new/codegen_backend_x86_ops_fpu.c index dd1e658fb..03734ca90 100644 --- a/src/cpu_new/codegen_backend_x86_ops_fpu.c +++ b/src/cpu_new/codegen_backend_x86_ops_fpu.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_ops_sse.c b/src/cpu_new/codegen_backend_x86_ops_sse.c index d829e4097..83a54f64a 100644 --- a/src/cpu_new/codegen_backend_x86_ops_sse.c +++ b/src/cpu_new/codegen_backend_x86_ops_sse.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_backend_x86_uops.c b/src/cpu_new/codegen_backend_x86_uops.c index 679a7b77b..af801382c 100644 --- a/src/cpu_new/codegen_backend_x86_uops.c +++ b/src/cpu_new/codegen_backend_x86_uops.c @@ -1,9 +1,9 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_block.c b/src/cpu_new/codegen_block.c index acff96a92..eec6d467c 100644 --- a/src/cpu_new/codegen_block.c +++ b/src/cpu_new/codegen_block.c @@ -1,8 +1,9 @@ #include #include -#include "../86box.h" +#include +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ir.c b/src/cpu_new/codegen_ir.c index 7d305737b..6aa2e6546 100644 --- a/src/cpu_new/codegen_ir.c +++ b/src/cpu_new/codegen_ir.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/cpu_new/codegen_ops.c b/src/cpu_new/codegen_ops.c index c1c6e54e7..2870c2b72 100644 --- a/src/cpu_new/codegen_ops.c +++ b/src/cpu_new/codegen_ops.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/cpu_new/codegen_ops_3dnow.c b/src/cpu_new/codegen_ops_3dnow.c index 2406fe8e0..c2c0e85a6 100644 --- a/src/cpu_new/codegen_ops_3dnow.c +++ b/src/cpu_new/codegen_ops_3dnow.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_arith.c b/src/cpu_new/codegen_ops_arith.c index 70eddd4a9..f2c85eeba 100644 --- a/src/cpu_new/codegen_ops_arith.c +++ b/src/cpu_new/codegen_ops_arith.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_branch.c b/src/cpu_new/codegen_ops_branch.c index 5bea31781..853b0308a 100644 --- a/src/cpu_new/codegen_ops_branch.c +++ b/src/cpu_new/codegen_ops_branch.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_fpu_arith.c b/src/cpu_new/codegen_ops_fpu_arith.c index 3f5621c3c..99384b3d4 100644 --- a/src/cpu_new/codegen_ops_fpu_arith.c +++ b/src/cpu_new/codegen_ops_fpu_arith.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_fpu_constant.c b/src/cpu_new/codegen_ops_fpu_constant.c index bca268ee3..cb048547c 100644 --- a/src/cpu_new/codegen_ops_fpu_constant.c +++ b/src/cpu_new/codegen_ops_fpu_constant.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_fpu_loadstore.c b/src/cpu_new/codegen_ops_fpu_loadstore.c index 599ab800e..879760518 100644 --- a/src/cpu_new/codegen_ops_fpu_loadstore.c +++ b/src/cpu_new/codegen_ops_fpu_loadstore.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_fpu_misc.c b/src/cpu_new/codegen_ops_fpu_misc.c index 7de92a39c..cb54ce791 100644 --- a/src/cpu_new/codegen_ops_fpu_misc.c +++ b/src/cpu_new/codegen_ops_fpu_misc.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_helpers.c b/src/cpu_new/codegen_ops_helpers.c index 9fc754e6c..feae979bb 100644 --- a/src/cpu_new/codegen_ops_helpers.c +++ b/src/cpu_new/codegen_ops_helpers.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_jump.c b/src/cpu_new/codegen_ops_jump.c index a4d2b8847..2e304abc3 100644 --- a/src/cpu_new/codegen_ops_jump.c +++ b/src/cpu_new/codegen_ops_jump.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_logic.c b/src/cpu_new/codegen_ops_logic.c index 87607ab2d..372fb2e60 100644 --- a/src/cpu_new/codegen_ops_logic.c +++ b/src/cpu_new/codegen_ops_logic.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_misc.c b/src/cpu_new/codegen_ops_misc.c index 3896e7ebc..d4c243f96 100644 --- a/src/cpu_new/codegen_ops_misc.c +++ b/src/cpu_new/codegen_ops_misc.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_arith.c b/src/cpu_new/codegen_ops_mmx_arith.c index 6b42273fa..91c6a61d0 100644 --- a/src/cpu_new/codegen_ops_mmx_arith.c +++ b/src/cpu_new/codegen_ops_mmx_arith.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_cmp.c b/src/cpu_new/codegen_ops_mmx_cmp.c index 649e8550f..187f15fc4 100644 --- a/src/cpu_new/codegen_ops_mmx_cmp.c +++ b/src/cpu_new/codegen_ops_mmx_cmp.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_loadstore.c b/src/cpu_new/codegen_ops_mmx_loadstore.c index 37ab3199a..a4413478e 100644 --- a/src/cpu_new/codegen_ops_mmx_loadstore.c +++ b/src/cpu_new/codegen_ops_mmx_loadstore.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_logic.c b/src/cpu_new/codegen_ops_mmx_logic.c index 4a554b238..3bd78ec70 100644 --- a/src/cpu_new/codegen_ops_mmx_logic.c +++ b/src/cpu_new/codegen_ops_mmx_logic.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_pack.c b/src/cpu_new/codegen_ops_mmx_pack.c index 6e9616271..9f1ae7aed 100644 --- a/src/cpu_new/codegen_ops_mmx_pack.c +++ b/src/cpu_new/codegen_ops_mmx_pack.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mmx_shift.c b/src/cpu_new/codegen_ops_mmx_shift.c index 014001d53..4f99050d5 100644 --- a/src/cpu_new/codegen_ops_mmx_shift.c +++ b/src/cpu_new/codegen_ops_mmx_shift.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_mov.c b/src/cpu_new/codegen_ops_mov.c index 87d7bc8bb..d6bfc85b6 100644 --- a/src/cpu_new/codegen_ops_mov.c +++ b/src/cpu_new/codegen_ops_mov.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "386_common.h" diff --git a/src/cpu_new/codegen_ops_shift.c b/src/cpu_new/codegen_ops_shift.c index 2d0b760d2..c3d5db504 100644 --- a/src/cpu_new/codegen_ops_shift.c +++ b/src/cpu_new/codegen_ops_shift.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_ops_stack.c b/src/cpu_new/codegen_ops_stack.c index 28b346446..eb1f4d18e 100644 --- a/src/cpu_new/codegen_ops_stack.c +++ b/src/cpu_new/codegen_ops_stack.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_flags.h" diff --git a/src/cpu_new/codegen_reg.c b/src/cpu_new/codegen_reg.c index 70b654998..b5af4a050 100644 --- a/src/cpu_new/codegen_reg.c +++ b/src/cpu_new/codegen_reg.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_backend.h" diff --git a/src/cpu_new/codegen_timing_486.c b/src/cpu_new/codegen_timing_486.c index b4054b32f..970514f29 100644 --- a/src/cpu_new/codegen_timing_486.c +++ b/src/cpu_new/codegen_timing_486.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_timing_686.c b/src/cpu_new/codegen_timing_686.c index 609a5e068..58afb7262 100644 --- a/src/cpu_new/codegen_timing_686.c +++ b/src/cpu_new/codegen_timing_686.c @@ -10,9 +10,9 @@ */ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_timing_common.c b/src/cpu_new/codegen_timing_common.c index 3b47a2734..5eaa7f532 100644 --- a/src/cpu_new/codegen_timing_common.c +++ b/src/cpu_new/codegen_timing_common.c @@ -1,7 +1,7 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "codegen_timing_common.h" diff --git a/src/cpu_new/codegen_timing_k6.c b/src/cpu_new/codegen_timing_k6.c index 9c216de9a..5aa05cb87 100644 --- a/src/cpu_new/codegen_timing_k6.c +++ b/src/cpu_new/codegen_timing_k6.c @@ -1,10 +1,10 @@ /*Most of the vector instructions here are a total guess. Some of the timings are based on http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" -#include "../machine/machine.h" +#include "mem.h" +#include "machine.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/codegen_timing_pentium.c b/src/cpu_new/codegen_timing_pentium.c index 1e4c104fd..f923646a6 100644 --- a/src/cpu_new/codegen_timing_pentium.c +++ b/src/cpu_new/codegen_timing_pentium.c @@ -11,12 +11,12 @@ */ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu_new/codegen_timing_winchip.c b/src/cpu_new/codegen_timing_winchip.c index f488078a5..53159a375 100644 --- a/src/cpu_new/codegen_timing_winchip.c +++ b/src/cpu_new/codegen_timing_winchip.c @@ -1,10 +1,10 @@ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "../mem.h" +#include "mem.h" #include "codegen.h" #include "codegen_ops.h" diff --git a/src/cpu_new/codegen_timing_winchip2.c b/src/cpu_new/codegen_timing_winchip2.c index e7294b917..360683522 100644 --- a/src/cpu_new/codegen_timing_winchip2.c +++ b/src/cpu_new/codegen_timing_winchip2.c @@ -8,9 +8,9 @@ - Instructions with prefixes can pair if both instructions are fully decoded when the first instruction starts execution.*/ #include -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../mem.h" +#include "mem.h" #include "x86.h" #include "x86_ops.h" diff --git a/src/cpu_new/x86_flags_dynarec.h b/src/cpu_new/x86_flags_dynarec.h deleted file mode 100644 index 2a5212afa..000000000 --- a/src/cpu_new/x86_flags_dynarec.h +++ /dev/null @@ -1,528 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -/* This file is needed so that the dynarec can use the old flags - functions, while the interpreter can use the new ones. */ -extern int tempc; - -enum -{ - FLAGS_UNKNOWN, - - FLAGS_ZN8, - FLAGS_ZN16, - FLAGS_ZN32, - - FLAGS_ADD8, - FLAGS_ADD16, - FLAGS_ADD32, - - FLAGS_SUB8, - FLAGS_SUB16, - FLAGS_SUB32, - - FLAGS_SHL8, - FLAGS_SHL16, - FLAGS_SHL32, - - FLAGS_SHR8, - FLAGS_SHR16, - FLAGS_SHR32, - - FLAGS_SAR8, - FLAGS_SAR16, - FLAGS_SAR32, - - FLAGS_INC8, - FLAGS_INC16, - FLAGS_INC32, - - FLAGS_DEC8, - FLAGS_DEC16, - FLAGS_DEC32 -}; - -static __inline int ZF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return !cpu_state.flags_res; - - case FLAGS_UNKNOWN: - return cpu_state.flags & Z_FLAG; - - default: - return 0; - } -} - -static __inline int NF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - return cpu_state.flags_res & 0x80; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - return cpu_state.flags_res & 0x8000; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - return cpu_state.flags_res & 0x80000000; - - case FLAGS_UNKNOWN: - return cpu_state.flags & N_FLAG; - - default: - return 0; - } -} - -static __inline int PF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; - - case FLAGS_UNKNOWN: - return cpu_state.flags & P_FLAG; - - default: - return 0; - } -} - -static __inline int VF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; - - case FLAGS_ADD8: - case FLAGS_INC8: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); - case FLAGS_ADD16: - case FLAGS_INC16: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); - case FLAGS_ADD32: - case FLAGS_INC32: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - - case FLAGS_SUB8: - case FLAGS_DEC8: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); - case FLAGS_SUB16: - case FLAGS_DEC16: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); - case FLAGS_SUB32: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - - case FLAGS_SHL8: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); - case FLAGS_SHL16: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); - case FLAGS_SHL32: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); - - case FLAGS_SHR8: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); - case FLAGS_SHR16: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); - case FLAGS_SHR32: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); - - case FLAGS_UNKNOWN: - return cpu_state.flags & V_FLAG; - - default: - return 0; - } -} - -static __inline int AF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; - - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; - - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; - - case FLAGS_UNKNOWN: - return cpu_state.flags & A_FLAG; - - default: - return 0; - } -} - -static __inline int CF_SET_dynarec() -{ - switch (cpu_state.flags_op) - { - case FLAGS_ADD8: - return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100; - case FLAGS_ADD16: - return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000; - case FLAGS_ADD32: - return (cpu_state.flags_res < cpu_state.flags_op1); - - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - return (cpu_state.flags_op1 < cpu_state.flags_op2); - - case FLAGS_SHL8: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80; - case FLAGS_SHL16: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000; - case FLAGS_SHL32: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000; - - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - - case FLAGS_SAR8: - return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR16: - return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR32: - return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - return 0; - - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_UNKNOWN: - return cpu_state.flags & C_FLAG; - - default: - return 0; - } -} - -static __inline void flags_rebuild_dynarec() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - uint16_t tempf = 0; - if (CF_SET_dynarec()) tempf |= C_FLAG; - if (PF_SET_dynarec()) tempf |= P_FLAG; - if (AF_SET_dynarec()) tempf |= A_FLAG; - if (ZF_SET_dynarec()) tempf |= Z_FLAG; - if (NF_SET_dynarec()) tempf |= N_FLAG; - if (VF_SET_dynarec()) tempf |= V_FLAG; - cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } -} - -static __inline void flags_extract_dynarec() -{ - cpu_state.flags_op = FLAGS_UNKNOWN; -} - -static __inline void flags_rebuild_c_dynarec() -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - if (CF_SET_dynarec()) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - } -} - -static __inline void setznp8_dynarec(uint8_t val) -{ - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = val; -} -static __inline void setznp16_dynarec(uint16_t val) -{ - cpu_state.flags_op = FLAGS_ZN16; - cpu_state.flags_res = val; -} -static __inline void setznp32_dynarec(uint32_t val) -{ - cpu_state.flags_op = FLAGS_ZN32; - cpu_state.flags_res = val; -} - -#define set_flags_shift_dynarec(op, orig, shift, res) \ - cpu_state.flags_op = op; \ - cpu_state.flags_res = res; \ - cpu_state.flags_op1 = orig; \ - cpu_state.flags_op2 = shift; - -static __inline void setadd8_dynarec(uint8_t a, uint8_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_ADD8; -} -static __inline void setadd16_dynarec(uint16_t a, uint16_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_ADD16; -} -static __inline void setadd32_dynarec(uint32_t a, uint32_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_ADD32; -} -static __inline void setadd8nc_dynarec(uint8_t a, uint8_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_INC8; -} -static __inline void setadd16nc_dynarec(uint16_t a, uint16_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_INC16; -} -static __inline void setadd32nc_dynarec(uint32_t a, uint32_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_INC32; -} - -static __inline void setsub8_dynarec(uint8_t a, uint8_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_SUB8; -} -static __inline void setsub16_dynarec(uint16_t a, uint16_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_SUB16; -} -static __inline void setsub32_dynarec(uint32_t a, uint32_t b) -{ - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_SUB32; -} - -static __inline void setsub8nc_dynarec(uint8_t a, uint8_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_DEC8; -} -static __inline void setsub16nc_dynarec(uint16_t a, uint16_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_DEC16; -} -static __inline void setsub32nc_dynarec(uint32_t a, uint32_t b) -{ - flags_rebuild_c_dynarec(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_DEC32; -} - -static __inline void setadc8_dynarec(uint8_t a, uint8_t b) -{ - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable8[c&0xFF]; - if (c&0x100) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; -} -static __inline void setadc16_dynarec(uint16_t a, uint16_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable16[c&0xFFFF]; - if (c&0x10000) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; -} -static __inline void setadc32_dynarec(uint32_t a, uint32_t b) -{ - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; -} - -extern void cpu_386_flags_extract(); -extern void cpu_386_flags_rebuild(); \ No newline at end of file diff --git a/src/cpu_new/x86seg.c b/src/cpu_new/x86seg.c index c07f002ea..12ad3753b 100644 --- a/src/cpu_new/x86seg.c +++ b/src/cpu_new/x86seg.c @@ -24,13 +24,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "cpu.h" -#include "../device.h" -#include "../timer.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../nvr.h" +#include "device.h" +#include "timer.h" +#include "machine.h" +#include "mem.h" +#include "nvr.h" #include "x86.h" #include "x86_flags.h" #include "386_common.h" diff --git a/src/cpu_table.d b/src/cpu_table.d new file mode 100644 index 000000000..f2237f4fc --- /dev/null +++ b/src/cpu_table.d @@ -0,0 +1,2 @@ +cpu_table.o: cpu_common/cpu_table.c 86box.h cpu_common/cpu.h \ + machine/machine.h diff --git a/src/cpu_table.txt b/src/cpu_table.txt new file mode 100644 index 000000000..038cebc74 --- /dev/null +++ b/src/cpu_table.txt @@ -0,0 +1,3 @@ +Comparing files CPU\cpu_table.c and CPU_NEW\CPU_TABLE.C +FC: no differences encountered + diff --git a/src/debug.d b/src/debug.d new file mode 100644 index 000000000..92cc83672 --- /dev/null +++ b/src/debug.d @@ -0,0 +1,9 @@ +debug.o: network/slirp/debug.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/device.c b/src/device.c index 97318c50d..905ae4a07 100644 --- a/src/device.c +++ b/src/device.c @@ -47,8 +47,8 @@ #include "86box.h" #include "config.h" #include "device.h" -#include "machine/machine.h" -#include "sound/sound.h" +#include "machine.h" +#include "sound.h" #define DEVICE_MAX 256 /* max # of devices */ @@ -172,6 +172,13 @@ device_add_common(const device_t *d, const device_t *cd, void *p, int inst) else device_log("DEVICE: device init successful\n"); + if (d->reset && (d->flags & DEVICE_PCI)) { + if (d->name) + pclog("DEVICE: [%08X] device '%s' init successful\n", d->reset, d->name); + else + pclog("DEVICE: [%08X] device init successful\n", d->reset); + } + memcpy(&device_current, &device_prev, sizeof(device_context_t)); device_priv[c] = priv; } else @@ -282,8 +289,10 @@ device_reset_all_pci(void) for (c=0; creset != NULL) && (devices[c]->flags & DEVICE_PCI)) + if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI)) { + pclog("Resetting %08X...\n", devices[c]->reset); devices[c]->reset(device_priv[c]); + } } } } diff --git a/src/device.d b/src/device.d new file mode 100644 index 000000000..013038f82 --- /dev/null +++ b/src/device.d @@ -0,0 +1,2 @@ +device.o: device.c 86box.h config.h device.h machine/machine.h \ + sound/sound.h diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 4b1313cb1..f6ed1ae35 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -22,9 +22,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../machine/machine.h" -#include "../device.h" +#include "86box.h" +#include "machine.h" +#include "device.h" #include "hdc.h" #include "hdc_ide.h" #include "hdd.h" diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 920c087d5..91f1071a4 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -28,17 +28,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index f70dd7db7..c3438e8dd 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -67,16 +67,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../dma.h" -#include "../io.h" -#include "../mca.h" -#include "../mem.h" -#include "../pic.h" -#include "../rom.h" -#include "../timer.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "dma.h" +#include "86box_io.h" +#include "mca.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "timer.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 5fedee57d..5ec684bc7 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -28,20 +28,20 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../mem.h" -#include "../pic.h" -#include "../pci.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" +#include "mem.h" +#include "pic.h" +#include "pci.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdc_ide.h" #include "hdd.h" diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 1e6fce712..2c58042ae 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -25,17 +25,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cdrom/cdrom.h" -#include "../scsi/scsi_device.h" -#include "../scsi/scsi_cdrom.h" -#include "../dma.h" -#include "../io.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../pci.h" -#include "../pic.h" +#include "86box.h" +#include "cdrom.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" +#include "dma.h" +#include "86box_io.h" +#include "device.h" +#include "keyboard.h" +#include "mem.h" +#include "pci.h" +#include "pic.h" #include "hdc.h" #include "hdc_ide.h" #include "hdc_ide_sff8038i.h" @@ -74,21 +74,24 @@ sff_log(const char *fmt, ...) void -sff_bus_master_handlers(sff8038i_t *dev, uint16_t old_base, uint16_t new_base, int enabled) +sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base) { - io_removehandler(old_base, 0x08, - sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, - sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, - dev); + if (dev->base != 0x0000) { + io_removehandler(dev->base, 0x08, + sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, + sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, + dev); + } - if (enabled && new_base) { - io_sethandler(new_base, 0x08, + if (enabled && (base != 0x0000)) { + io_sethandler(base, 0x08, sff_bus_master_read, sff_bus_master_readw, sff_bus_master_readl, sff_bus_master_write, sff_bus_master_writew, sff_bus_master_writel, dev); } dev->enabled = enabled; + dev->base = base; } diff --git a/src/disk/hdc_ide_sff8038i.h b/src/disk/hdc_ide_sff8038i.h index 16b6ce524..bad14a7c6 100644 --- a/src/disk/hdc_ide_sff8038i.h +++ b/src/disk/hdc_ide_sff8038i.h @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)hdc_ide_sff8038i.h 1.0.1 2020/01/14 + * Version: @(#)hdc_ide_sff8038i.h 1.0.2 2020/01/26 * * Authors: Sarah Walker, * Miran Grca, @@ -20,6 +20,7 @@ typedef struct { uint8_t command, status, ptr0, enabled; + uint16_t base, pad; uint32_t ptr, ptr_cur, addr; int count, eot, @@ -30,7 +31,7 @@ typedef struct extern const device_t sff8038i_device; -extern void sff_bus_master_handlers(sff8038i_t *dev, uint16_t old_base, uint16_t new_base, int enabled); +extern void sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base); extern int sff_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv); extern int sff_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv); diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index 683ade1fc..a6da77d30 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -30,15 +30,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../pic.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "pic.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index a980ec6e8..f096879c6 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -77,16 +77,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../ui.h" -#include "../plat.h" -#include "../dma.h" -#include "../pic.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "ui.h" +#include "plat.h" +#include "dma.h" +#include "pic.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index c821ef98d..9a3d57186 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -94,16 +94,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdd.h" diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index 2e7a5b359..26ef50cb8 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -36,11 +36,11 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "hdc.h" #include "hdc_ide.h" diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 97bbf3ddb..6163e8e06 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -20,11 +20,11 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "plat.h" +#include "ui.h" #include "hdd.h" -#include "../cdrom/cdrom.h" +#include "cdrom.h" hard_disk_t hdd[HDD_NUM]; diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 6a6e4ee02..7002c0634 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -28,9 +28,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../plat.h" -#include "../random.h" +#include "86box.h" +#include "plat.h" +#include "random.h" #include "hdd.h" diff --git a/src/disk/hdd_table.c b/src/disk/hdd_table.c index 0ef0829e1..7a68fdb99 100644 --- a/src/disk/hdd_table.c +++ b/src/disk/hdd_table.c @@ -22,7 +22,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "hdd.h" diff --git a/src/disk/zip.c b/src/disk/zip.c index 1bbec776b..e0fc5d783 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -22,16 +22,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi_device.h" -#include "../nvr.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "config.h" +#include "timer.h" +#include "device.h" +#include "piix.h" +#include "scsi_device.h" +#include "nvr.h" +#include "plat.h" +#include "ui.h" #include "hdc.h" #include "hdc_ide.h" #include "zip.h" diff --git a/src/dma.c b/src/dma.c index f9a02f365..802c0e836 100644 --- a/src/dma.c +++ b/src/dma.c @@ -8,7 +8,7 @@ * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.c 1.0.8 2020/01/14 + * Version: @(#)dma.c 1.0.9 2020/01/26 * * Authors: Sarah Walker, * Miran Grca, @@ -23,17 +23,12 @@ #include #include #include "86box.h" -#ifdef USE_NEW_DYNAREC -#include "cpu_new/cpu.h" -#include "cpu_new/x86.h" -#else -#include "cpu/cpu.h" -#include "cpu/x86.h" -#endif +#include "cpu_common/cpu.h" +#include "cpu_common/x86.h" #include "machine/machine.h" #include "mca.h" #include "mem.h" -#include "io.h" +#include "86box_io.h" #include "dma.h" @@ -672,6 +667,20 @@ dma_alias_set(void) } +void +dma_alias_set_piix(void) +{ + io_sethandler(0x0090, 1, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x0094, 3, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x0098, 1, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); + io_sethandler(0x009C, 3, + dma_page_read,NULL,NULL, dma_page_write,NULL,NULL, NULL); +} + + void dma_alias_remove(void) { diff --git a/src/dma.d b/src/dma.d new file mode 100644 index 000000000..52ef2c3e7 --- /dev/null +++ b/src/dma.d @@ -0,0 +1,2 @@ +dma.o: dma.c 86box.h cpu_common/cpu.h cpu_common/x86.h machine/machine.h \ + mca.h mem.h 86box_io.h dma.h diff --git a/src/dma.h b/src/dma.h index 5340ba2ea..7761107f1 100644 --- a/src/dma.h +++ b/src/dma.h @@ -8,7 +8,7 @@ * * Definitions for the Intel DMA controller. * - * Version: @(#)dma.h 1.0.3 2020/01/14 + * Version: @(#)dma.h 1.0.4 2020/01/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -86,6 +86,7 @@ extern int dma_channel_read(int channel); extern int dma_channel_write(int channel, uint16_t val); extern void dma_alias_set(void); +extern void dma_alias_set_piix(void); extern void dma_alias_remove(void); extern void dma_alias_remove_piix(void); diff --git a/src/envelope.d b/src/envelope.d new file mode 100644 index 000000000..231ba6547 --- /dev/null +++ b/src/envelope.d @@ -0,0 +1,2 @@ +envelope.o: sound/resid-fp/envelope.cc sound/resid-fp/envelope.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/extfilt.d b/src/extfilt.d new file mode 100644 index 000000000..c37f25691 --- /dev/null +++ b/src/extfilt.d @@ -0,0 +1,2 @@ +extfilt.o: sound/resid-fp/extfilt.cc sound/resid-fp/extfilt.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/fdc.d b/src/fdc.d new file mode 100644 index 000000000..2759b4139 --- /dev/null +++ b/src/fdc.d @@ -0,0 +1,2 @@ +fdc.o: floppy/fdc.c 86box.h device.h cpu_common/cpu.h machine/machine.h \ + 86box_io.h dma.h pic.h timer.h ui.h floppy/fdd.h floppy/fdc.h diff --git a/src/fdd.d b/src/fdd.d new file mode 100644 index 000000000..a2fd752fb --- /dev/null +++ b/src/fdd.d @@ -0,0 +1,4 @@ +fdd.o: floppy/fdd.c 86box.h timer.h cpu_common/cpu.h plat.h \ + lang/language.h ui.h floppy/fdd.h floppy/fdd_86f.h floppy/fdd_fdi.h \ + floppy/fdd_imd.h floppy/fdd_img.h floppy/fdd_json.h floppy/fdd_mfm.h \ + floppy/fdd_td0.h floppy/fdc.h diff --git a/src/fdd_86f.d b/src/fdd_86f.d new file mode 100644 index 000000000..1ff41be35 --- /dev/null +++ b/src/fdd_86f.d @@ -0,0 +1,3 @@ +fdd_86f.o: floppy/fdd_86f.c 86box.h timer.h cpu_common/cpu.h dma.h nvr.h \ + random.h plat.h lang/language.h ui.h floppy/fdd.h floppy/fdc.h \ + floppy/fdd_86f.h diff --git a/src/fdd_common.d b/src/fdd_common.d new file mode 100644 index 000000000..a55004324 --- /dev/null +++ b/src/fdd_common.d @@ -0,0 +1,2 @@ +fdd_common.o: floppy/fdd_common.c 86box.h timer.h cpu_common/cpu.h \ + floppy/fdd.h floppy/fdd_common.h diff --git a/src/fdd_fdi.d b/src/fdd_fdi.d new file mode 100644 index 000000000..25217baf1 --- /dev/null +++ b/src/fdd_fdi.d @@ -0,0 +1,3 @@ +fdd_fdi.o: floppy/fdd_fdi.c 86box.h timer.h cpu_common/cpu.h plat.h \ + lang/language.h floppy/fdd.h floppy/fdd_86f.h floppy/fdd_img.h \ + floppy/fdd_fdi.h floppy/fdc.h floppy/fdi2raw.h diff --git a/src/fdd_imd.d b/src/fdd_imd.d new file mode 100644 index 000000000..eba24f140 --- /dev/null +++ b/src/fdd_imd.d @@ -0,0 +1,3 @@ +fdd_imd.o: floppy/fdd_imd.c 86box.h timer.h cpu_common/cpu.h plat.h \ + lang/language.h floppy/fdd.h floppy/fdd_86f.h floppy/fdd_imd.h \ + floppy/fdc.h diff --git a/src/fdd_img.d b/src/fdd_img.d new file mode 100644 index 000000000..b7f57f21f --- /dev/null +++ b/src/fdd_img.d @@ -0,0 +1,3 @@ +fdd_img.o: floppy/fdd_img.c 86box.h timer.h cpu_common/cpu.h config.h \ + plat.h lang/language.h floppy/fdd.h floppy/fdd_86f.h floppy/fdd_img.h \ + floppy/fdc.h diff --git a/src/fdd_json.d b/src/fdd_json.d new file mode 100644 index 000000000..5a4299f5f --- /dev/null +++ b/src/fdd_json.d @@ -0,0 +1,3 @@ +fdd_json.o: floppy/fdd_json.c 86box.h timer.h cpu_common/cpu.h plat.h \ + lang/language.h floppy/fdd.h floppy/fdd_86f.h floppy/fdc.h \ + floppy/fdd_common.h floppy/fdd_json.h diff --git a/src/fdd_mfm.d b/src/fdd_mfm.d new file mode 100644 index 000000000..5980352cf --- /dev/null +++ b/src/fdd_mfm.d @@ -0,0 +1,3 @@ +fdd_mfm.o: floppy/fdd_mfm.c 86box.h timer.h cpu_common/cpu.h plat.h \ + lang/language.h floppy/fdd.h floppy/fdd_86f.h floppy/fdd_img.h \ + floppy/fdd_mfm.h floppy/fdc.h diff --git a/src/fdd_td0.d b/src/fdd_td0.d new file mode 100644 index 000000000..3e55a1657 --- /dev/null +++ b/src/fdd_td0.d @@ -0,0 +1,3 @@ +fdd_td0.o: floppy/fdd_td0.c 86box.h timer.h cpu_common/cpu.h plat.h \ + lang/language.h floppy/fdd.h floppy/fdd_86f.h floppy/fdd_td0.h \ + floppy/fdc.h diff --git a/src/fdi2raw.d b/src/fdi2raw.d new file mode 100644 index 000000000..a971f5b0e --- /dev/null +++ b/src/fdi2raw.d @@ -0,0 +1 @@ +fdi2raw.o: floppy/fdi2raw.c 86box.h floppy/fdi2raw.h diff --git a/src/filter.d b/src/filter.d new file mode 100644 index 000000000..55ad4e3f5 --- /dev/null +++ b/src/filter.d @@ -0,0 +1,4 @@ +filter.o: sound/resid-fp/filter.cc sound/resid-fp/filter.h \ + sound/resid-fp/siddefs-fp.h sound/resid-fp/sid.h sound/resid-fp/voice.h \ + sound/resid-fp/wave.h sound/resid-fp/envelope.h sound/resid-fp/extfilt.h \ + sound/resid-fp/pot.h diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 495f8c3d1..81274199c 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -9,13 +9,13 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.c 1.0.21 2019/10/20 + * Version: @(#)fdc.c 1.0.22 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -24,15 +24,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" +#include "ui.h" #include "fdd.h" #include "fdc.h" @@ -1994,6 +1994,13 @@ fdc_set_swap(fdc_t *fdc, uint8_t swap) } +void +fdc_set_irq(fdc_t *fdc, int irq) +{ + fdc->irq = irq; +} + + void fdc_set_base(fdc_t *fdc, int base) { diff --git a/src/floppy/fdc.h b/src/floppy/fdc.h index c6c3a90bf..786d1bfe5 100644 --- a/src/floppy/fdc.h +++ b/src/floppy/fdc.h @@ -9,15 +9,15 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.h 1.0.8 2019/10/20 + * Version: @(#)fdc.h 1.0.9 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2018,2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2018-2020 Fred N. van Kempen. */ #ifndef EMU_FDC_H # define EMU_FDC_H @@ -154,6 +154,7 @@ extern int fdc_is_verify(fdc_t *fdc); extern void fdc_overrun(fdc_t *fdc); extern void fdc_set_base(fdc_t *fdc, int base); +extern void fdc_set_irq(fdc_t *fdc, int irq); extern int fdc_getdata(fdc_t *fdc, int last); extern int fdc_data(fdc_t *fdc, uint8_t data); diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 24bd46313..37f100002 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -24,10 +24,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" +#include "ui.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_fdi.h" diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 860c424c2..d55f86734 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -26,13 +26,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../dma.h" -#include "../nvr.h" -#include "../random.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "dma.h" +#include "nvr.h" +#include "random.h" +#include "plat.h" +#include "ui.h" #include "fdd.h" #include "fdc.h" #include "fdd_86f.h" diff --git a/src/floppy/fdd_common.c b/src/floppy/fdd_common.c index 3b3bfa338..3ad3db4aa 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -19,8 +19,8 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" +#include "86box.h" +#include "timer.h" #include "fdd.h" #include "fdd_common.h" diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index f9e42ed6b..04315377a 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -26,9 +26,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_img.h" diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index a9c9c21fa..14078ee01 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -23,9 +23,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_imd.h" diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index e1417254a..54039a320 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -30,10 +30,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../config.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "config.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_img.h" diff --git a/src/floppy/fdd_json.c b/src/floppy/fdd_json.c index 465e1d6a0..9b96f0c3b 100644 --- a/src/floppy/fdd_json.c +++ b/src/floppy/fdd_json.c @@ -51,9 +51,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdc.h" diff --git a/src/floppy/fdd_mfm.c b/src/floppy/fdd_mfm.c index 507a0c0a2..13d9e88a0 100644 --- a/src/floppy/fdd_mfm.c +++ b/src/floppy/fdd_mfm.c @@ -22,9 +22,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_img.h" diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index a230a7ae8..b7517f437 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -35,9 +35,9 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "plat.h" #include "fdd.h" #include "fdd_86f.h" #include "fdd_td0.h" diff --git a/src/floppy/fdi2raw.c b/src/floppy/fdi2raw.c index d01054e97..bf54babfb 100644 --- a/src/floppy/fdi2raw.c +++ b/src/floppy/fdi2raw.c @@ -37,7 +37,7 @@ /* ELSE */ #define xmalloc malloc #define HAVE_STDARG_H -#include "../86box.h" +#include "86box.h" #include "fdi2raw.h" diff --git a/src/game/gameport.c b/src/game/gameport.c index e41489111..f2c545a26 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -39,12 +39,12 @@ #include #include #include -#include "../86box.h" -#include "../machine/machine.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../io.h" -#include "../timer.h" +#include "86box.h" +#include "machine.h" +#include "cpu.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 062e753a6..5b7b99da8 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -39,9 +39,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_standard.h" diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index e207b5173..29b31f590 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -39,9 +39,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_standard.h" diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 09030d8ad..5a8c0d284 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -60,9 +60,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_sw_pad.h" diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 69fa19d2b..afb4ac1b5 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -39,9 +39,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "timer.h" #include "gameport.h" #include "joystick_standard.h" diff --git a/src/gameport.d b/src/gameport.d new file mode 100644 index 000000000..97f10b9a9 --- /dev/null +++ b/src/gameport.d @@ -0,0 +1,4 @@ +gameport.o: game/gameport.c 86box.h machine/machine.h cpu_common/cpu.h \ + device.h 86box_io.h timer.h game/gameport.h \ + game/joystick_ch_flightstick_pro.h game/joystick_standard.h \ + game/joystick_sw_pad.h game/joystick_tm_fcs.h diff --git a/src/hdc.d b/src/hdc.d new file mode 100644 index 000000000..837d6b82c --- /dev/null +++ b/src/hdc.d @@ -0,0 +1,2 @@ +hdc.o: disk/hdc.c 86box.h machine/machine.h device.h disk/hdc.h \ + disk/hdc_ide.h disk/hdd.h diff --git a/src/hdc_esdi_at.d b/src/hdc_esdi_at.d new file mode 100644 index 000000000..da819fedd --- /dev/null +++ b/src/hdc_esdi_at.d @@ -0,0 +1,3 @@ +hdc_esdi_at.o: disk/hdc_esdi_at.c 86box.h device.h 86box_io.h mem.h pic.h \ + rom.h cpu_common/cpu.h machine/machine.h timer.h plat.h lang/language.h \ + ui.h disk/hdc.h disk/hdd.h diff --git a/src/hdc_esdi_mca.d b/src/hdc_esdi_mca.d new file mode 100644 index 000000000..9c3637c71 --- /dev/null +++ b/src/hdc_esdi_mca.d @@ -0,0 +1,3 @@ +hdc_esdi_mca.o: disk/hdc_esdi_mca.c 86box.h device.h dma.h 86box_io.h \ + mca.h mem.h pic.h rom.h timer.h cpu_common/cpu.h ui.h disk/hdc.h \ + disk/hdd.h diff --git a/src/hdc_ide.d b/src/hdc_ide.d new file mode 100644 index 000000000..476642e57 --- /dev/null +++ b/src/hdc_ide.d @@ -0,0 +1,4 @@ +hdc_ide.o: disk/hdc_ide.c 86box.h cpu_common/cpu.h machine/machine.h \ + 86box_io.h mem.h pic.h pci.h rom.h timer.h device.h scsi/scsi_device.h \ + cdrom/cdrom.h plat.h lang/language.h ui.h disk/hdc.h disk/hdc_ide.h \ + disk/hdd.h disk/zip.h diff --git a/src/hdc_ide_sff8038i.d b/src/hdc_ide_sff8038i.d new file mode 100644 index 000000000..656c9b77b --- /dev/null +++ b/src/hdc_ide_sff8038i.d @@ -0,0 +1,4 @@ +hdc_ide_sff8038i.o: disk/hdc_ide_sff8038i.c 86box.h cdrom/cdrom.h \ + scsi/scsi_device.h scsi/scsi_cdrom.h dma.h 86box_io.h device.h \ + keyboard.h mem.h pci.h pic.h disk/hdc.h disk/hdc_ide.h \ + disk/hdc_ide_sff8038i.h disk/zip.h diff --git a/src/hdc_st506_at.d b/src/hdc_st506_at.d new file mode 100644 index 000000000..d2007be1b --- /dev/null +++ b/src/hdc_st506_at.d @@ -0,0 +1,3 @@ +hdc_st506_at.o: disk/hdc_st506_at.c 86box.h device.h 86box_io.h pic.h \ + cpu_common/cpu.h machine/machine.h timer.h plat.h lang/language.h ui.h \ + disk/hdc.h disk/hdd.h diff --git a/src/hdc_st506_xt.d b/src/hdc_st506_xt.d new file mode 100644 index 000000000..a1f5632f7 --- /dev/null +++ b/src/hdc_st506_xt.d @@ -0,0 +1,3 @@ +hdc_st506_xt.o: disk/hdc_st506_xt.c 86box.h 86box_io.h mem.h rom.h \ + timer.h cpu_common/cpu.h device.h ui.h plat.h lang/language.h dma.h \ + pic.h disk/hdc.h disk/hdd.h diff --git a/src/hdc_xta.d b/src/hdc_xta.d new file mode 100644 index 000000000..dd48faf1b --- /dev/null +++ b/src/hdc_xta.d @@ -0,0 +1,3 @@ +hdc_xta.o: disk/hdc_xta.c 86box.h 86box_io.h dma.h pic.h mem.h rom.h \ + device.h timer.h cpu_common/cpu.h plat.h lang/language.h ui.h disk/hdc.h \ + disk/hdd.h diff --git a/src/hdc_xtide.d b/src/hdc_xtide.d new file mode 100644 index 000000000..436aa361f --- /dev/null +++ b/src/hdc_xtide.d @@ -0,0 +1,2 @@ +hdc_xtide.o: disk/hdc_xtide.c 86box.h 86box_io.h mem.h rom.h device.h \ + disk/hdc.h disk/hdc_ide.h diff --git a/src/hdd.d b/src/hdd.d new file mode 100644 index 000000000..07777f193 --- /dev/null +++ b/src/hdd.d @@ -0,0 +1,2 @@ +hdd.o: disk/hdd.c 86box.h plat.h lang/language.h ui.h disk/hdd.h \ + cdrom/cdrom.h diff --git a/src/hdd_image.d b/src/hdd_image.d new file mode 100644 index 000000000..317c6d8d5 --- /dev/null +++ b/src/hdd_image.d @@ -0,0 +1,2 @@ +hdd_image.o: disk/hdd_image.c 86box.h plat.h lang/language.h random.h \ + disk/hdd.h diff --git a/src/hdd_table.d b/src/hdd_table.d new file mode 100644 index 000000000..7de62f4da --- /dev/null +++ b/src/hdd_table.d @@ -0,0 +1 @@ +hdd_table.o: disk/hdd_table.c 86box.h disk/hdd.h diff --git a/src/headland.d b/src/headland.d new file mode 100644 index 000000000..9cd091798 --- /dev/null +++ b/src/headland.d @@ -0,0 +1,3 @@ +headland.o: chipset/headland.c 86box.h cpu_common/cpu.h cpu_common/x86.h \ + timer.h 86box_io.h mem.h rom.h device.h keyboard.h floppy/fdd.h \ + floppy/fdc.h port_92.h chipset/chipset.h diff --git a/src/i82335.c b/src/i82335.c index 37cf60306..7be061601 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -4,7 +4,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "mem.h" typedef struct diff --git a/src/ibm_5161.c b/src/ibm_5161.c index 7cf6fed64..2374bdec3 100644 --- a/src/ibm_5161.c +++ b/src/ibm_5161.c @@ -19,7 +19,7 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "apm.h" #include "dma.h" #include "mem.h" @@ -27,7 +27,7 @@ #include "timer.h" #include "pit.h" #include "port_92.h" -#include "machine/machine.h" +#include "machine.h" #include "intel_sio.h" diff --git a/src/ibm_5161.d b/src/ibm_5161.d new file mode 100644 index 000000000..f855a05c4 --- /dev/null +++ b/src/ibm_5161.d @@ -0,0 +1,3 @@ +ibm_5161.o: ibm_5161.c 86box.h device.h 86box_io.h apm.h dma.h mem.h \ + pci.h timer.h cpu_common/cpu.h pit.h port_92.h machine/machine.h \ + intel_sio.h diff --git a/src/if.d b/src/if.d new file mode 100644 index 000000000..37b6cff68 --- /dev/null +++ b/src/if.d @@ -0,0 +1,8 @@ +if.o: network/slirp/if.c network/slirp/slirp.h network/slirp/config.h \ + network/slirp/config-host.h network/slirp/slirp_config.h \ + network/slirp/debug.h network/slirp/ip.h network/slirp/tcp.h \ + network/slirp/tcp_var.h network/slirp/tcpip.h network/slirp/tcp_timer.h \ + network/slirp/udp.h network/slirp/icmp_var.h network/slirp/mbuf.h \ + network/slirp/sbuf.h network/slirp/socket.h network/slirp/if.h \ + network/slirp/main.h network/slirp/misc.h network/slirp/ctl.h \ + network/slirp/bootp.h network/slirp/tftp.h network/slirp/libslirp.h diff --git a/src/intel_4x0.d b/src/intel_4x0.d new file mode 100644 index 000000000..da4717d4e --- /dev/null +++ b/src/intel_4x0.d @@ -0,0 +1,2 @@ +intel_4x0.o: chipset/intel_4x0.c 86box.h cpu_common/cpu.h mem.h \ + 86box_io.h rom.h pci.h device.h keyboard.h chipset/chipset.h diff --git a/src/intel_flash - Cópia.c b/src/intel_flash - Cópia.c new file mode 100644 index 000000000..cb08eb44b --- /dev/null +++ b/src/intel_flash - Cópia.c @@ -0,0 +1,561 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 1 Mbit and 2 Mbit, 8-bit and + * 16-bit flash devices. + * + * Version: @(#)intel_flash.c 1.0.19 2019/06/25 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "machine.h" +#include "timer.h" +#include "nvr.h" +#include "plat.h" + + +#define FLAG_BYTEMODE 4 +#define FLAG_WORD 4 +#define FLAG_BXB 2 +#define FLAG_INV_A16 1 + + +enum +{ + BLOCK_MAIN1, + BLOCK_MAIN2, + BLOCK_DATA1, + BLOCK_DATA2, + BLOCK_BOOT, + BLOCKS_NUM +}; + +enum +{ + CMD_READ_ARRAY = 0xff, + CMD_IID = 0x90, + CMD_READ_STATUS = 0x70, + CMD_CLEAR_STATUS = 0x50, + CMD_ERASE_SETUP = 0x20, + CMD_ERASE_CONFIRM = 0xd0, + CMD_ERASE_SUSPEND = 0xb0, + CMD_PROGRAM_SETUP = 0x40, + CMD_PROGRAM_SETUP_ALT = 0x10 +}; + + +typedef struct flash_t +{ + uint8_t command, status, + pad, flags, + *array; + + uint16_t flash_id, pad16; + + uint32_t program_addr, + block_start[BLOCKS_NUM], block_end[BLOCKS_NUM], + block_len[BLOCKS_NUM]; + + mem_mapping_t mapping[4], mapping_h[8]; +} flash_t; + + +static wchar_t flash_path[1024]; + + +static uint16_t flash_readw(uint32_t addr, void *p); + + +static uint8_t +flash_read(uint32_t addr, void *p) +{ + flash_t *dev = (flash_t *) p; + uint8_t ret = 0xff; + + if (dev->flags & FLAG_WORD) + return flash_readw(addr, p) & 0xff; + + if (dev->flags & FLAG_INV_A16) + addr ^= 0x10000; + addr &= biosmask; + + switch (dev->command) { + case CMD_READ_ARRAY: + default: + ret = dev->array[addr]; + break; + + case CMD_IID: + /* Yes, & 2 is correct for the 100BX/200BX in BYTE mode. */ + if (addr & 1) + ret = dev->flash_id & 0xff; + else + ret = 0x89; + // pclog("id b %i: %02X\n", addr & 1, ret); + break; + + case CMD_READ_STATUS: + ret = dev->status; + break; + } + +#if 0 + if ((dev->command & 0x0f) && (dev->command != 0xff)) + ret = dev->status; +#endif + + return ret; +} + + +static uint16_t +flash_readw(uint32_t addr, void *p) +{ + flash_t *dev = (flash_t *) p; + uint16_t *q; + uint16_t ret = 0xffff; + + if (!(dev->flags & FLAG_WORD)) + return flash_read(addr, p) | (flash_read(addr + 1, p) << 8); + + if (dev->flags & FLAG_INV_A16) + addr ^= 0x10000; + addr &= biosmask; + + if (dev->flags & FLAG_WORD) + addr &= 0xfffffffe; + + q = (uint16_t *)&(dev->array[addr]); + ret = *q; + + switch (dev->command) { + case CMD_READ_ARRAY: + default: + break; + + case CMD_IID: + // pclog("id w %i: %02X\n", addr & 2, ret); + if (addr & 2) + ret = dev->flash_id; + else + ret = 0x0089; + break; + + case CMD_READ_STATUS: + ret = dev->status; + break; + } + + return ret; +} + + +static uint32_t +flash_readl(uint32_t addr, void *p) +{ + flash_t *dev = (flash_t *)p; + uint32_t *q; + + if (dev->flags & FLAG_INV_A16) + addr ^= 0x10000; + addr &= biosmask; + + q = (uint32_t *)&(dev->array[addr]); + + return *q; + // return flash_readw(addr, p) | (flash_readw(addr + 2, p) << 16); +} + + +static void flash_writew(uint32_t addr, uint16_t val, void *p); + + +static void +flash_write(uint32_t addr, uint8_t val, void *p) +{ + flash_t *dev = (flash_t *) p; + int i; + uint32_t bb_mask = biosmask & 0xffffe000; + uint32_t o = addr; + if (biosmask == 0x3ffff) + bb_mask &= 0xffffc000; + + if (dev->flags & FLAG_WORD) { + flash_writew(addr, val, p); + return; + } + + if (dev->flags & FLAG_INV_A16) + addr ^= 0x10000; + addr &= biosmask; + + if ((addr >= 0x2e400) && (addr <= 0x2e43f)) { + dev->array[addr] = val; + return; + } + + switch (dev->command) { + case CMD_ERASE_SETUP: + if (val == CMD_ERASE_CONFIRM) { + for (i = 0; i < 3; i++) { + if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) + memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]); + } + + dev->status = 0x80; + } + dev->command = CMD_READ_STATUS; + break; + + case CMD_PROGRAM_SETUP: + case CMD_PROGRAM_SETUP_ALT: + if (((addr & bb_mask) != (dev->block_start[4] & bb_mask)) && (addr == dev->program_addr)) + dev->array[addr] = val; + dev->command = CMD_READ_STATUS; + dev->status = 0x80; + break; + + default: + dev->command = val; + // pclog("[%04X:%08X] (%08X, %02X) [%08X] command b = %02X\n", CS, cpu_state.pc, cpu_state.seg_cs.base, opcode, o, dev->command); +#if 0 + if (val == 0x93) { + FILE *f = fopen("d:\\queen\\86boxnew\\mem.dmp", "wb"); + for (i = 0; i < 1114096; i++) + fputc(mem_readb_phys(i), f); + fclose(f); + f = fopen("d:\\queen\\86boxnew\\highbios.dmp", "wb"); + for (i = 0; i < 524288; i++) + fputc(mem_readb_phys(i + 0xfff80000), f); + fclose(f); + fatal("Fo' shizzle da nizzle\n"); + } +#endif + switch (val) { + case CMD_CLEAR_STATUS: + dev->status = 0; + break; + case CMD_PROGRAM_SETUP: + case CMD_PROGRAM_SETUP_ALT: + dev->program_addr = addr; + break; + } + } +} + + +static void +flash_writew(uint32_t addr, uint16_t val, void *p) +{ + flash_t *dev = (flash_t *) p; + int i; + uint32_t bb_mask = biosmask & 0xffffe000; + if (biosmask == 0x3ffff) + bb_mask &= 0xffffc000; + + if (!(dev->flags & FLAG_WORD)) { + // flash_write(addr, val & 0xff, p); + // flash_write(addr + 1, (val >> 8) & 0xff, p); + return; + } + + if (dev->flags & FLAG_INV_A16) + addr ^= 0x10000; + addr &= biosmask; + + if (dev->flags & FLAG_WORD) switch (dev->command) { + case CMD_ERASE_SETUP: + if (val == CMD_ERASE_CONFIRM) { + for (i = 0; i < 3; i++) { + if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) + memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]); + } + + dev->status = 0x80; + } + dev->command = CMD_READ_STATUS; + break; + + case CMD_PROGRAM_SETUP: + case CMD_PROGRAM_SETUP_ALT: + if (((addr & bb_mask) != (dev->block_start[4] & bb_mask)) && (addr == dev->program_addr)) + *(uint16_t *) (&dev->array[addr]) = val; + dev->command = CMD_READ_STATUS; + dev->status = 0x80; + break; + + default: + dev->command = val & 0xff; + // pclog("command w = %02X\n", dev->command); + switch (val) { + case CMD_CLEAR_STATUS: + dev->status = 0; + break; + case CMD_PROGRAM_SETUP: + case CMD_PROGRAM_SETUP_ALT: + dev->program_addr = addr; + break; + } + } +} + + +static void +flash_writel(uint32_t addr, uint32_t val, void *p) +{ + flash_writew(addr, val & 0xffff, p); + flash_writew(addr + 2, (val >> 16) & 0xffff, p); +} + + +static void +intel_flash_add_mappings(flash_t *dev) +{ + int max = 2, i = 0; + uint32_t base, fbase; + uint32_t sub = 0x20000; + + if (biosmask == 0x3ffff) { + sub = 0x40000; + max = 4; + } + + for (i = 0; i < max; i++) { + if (biosmask == 0x3ffff) + base = 0xc0000 + (i << 16); + else + base = 0xe0000 + (i << 16); + fbase = base & biosmask; + if (dev->flags & FLAG_INV_A16) + fbase ^= 0x10000; + + memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000); + + if ((max == 2) || (i >= 2)) { + mem_mapping_add(&(dev->mapping[i]), base, 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, flash_writew, flash_writel, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + } + mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, flash_writew, flash_writel, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + mem_mapping_add(&(dev->mapping_h[i + 4]), (base | 0xfff00000), 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, flash_writew, flash_writel, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + } +} + + +static void * +intel_flash_init(const device_t *info) +{ + FILE *f; + int l; + flash_t *dev; + wchar_t *machine_name, *flash_name; + uint8_t type = info->local & 0xff; + + dev = malloc(sizeof(flash_t)); + memset(dev, 0, sizeof(flash_t)); + + l = strlen(machine_get_internal_name_ex(machine))+1; + machine_name = (wchar_t *) malloc(l * sizeof(wchar_t)); + mbstowcs(machine_name, machine_get_internal_name_ex(machine), l); + l = wcslen(machine_name)+5; + flash_name = (wchar_t *)malloc(l*sizeof(wchar_t)); + swprintf(flash_name, l, L"%ls.bin", machine_name); + + if (wcslen(flash_name) <= 1024) + wcscpy(flash_path, flash_name); + else + wcsncpy(flash_path, flash_name, 1024); + + dev->flags = info->local & 0xff; + + mem_mapping_disable(&bios_mapping); + mem_mapping_disable(&bios_high_mapping); + + dev->array = (uint8_t *) malloc(biosmask + 1); + memset(dev->array, 0xff, biosmask + 1); + + if (biosmask == 0x3ffff) { + if (dev->flags & FLAG_WORD) + dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274; + else + dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C; + + /* The block lengths are the same both flash types. */ + dev->block_len[BLOCK_MAIN1] = 0x20000; + dev->block_len[BLOCK_MAIN2] = 0x18000; + dev->block_len[BLOCK_DATA1] = 0x02000; + dev->block_len[BLOCK_DATA2] = 0x02000; + dev->block_len[BLOCK_BOOT] = 0x04000; + + if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */ + dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */ + dev->block_end[BLOCK_MAIN1] = 0x3ffff; + dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */ + dev->block_end[BLOCK_MAIN2] = 0x1ffff; + dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */ + dev->block_end[BLOCK_DATA1] = 0x07fff; + dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ + dev->block_end[BLOCK_DATA2] = 0x05fff; + dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + dev->block_end[BLOCK_BOOT] = 0x03fff; + } else { /* 28F002BX-T/28F200BX-T */ + dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */ + dev->block_end[BLOCK_MAIN1] = 0x1ffff; + dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */ + dev->block_end[BLOCK_MAIN2] = 0x37fff; + dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */ + dev->block_end[BLOCK_DATA1] = 0x39fff; + dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */ + dev->block_end[BLOCK_DATA2] = 0x3bfff; + dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */ + dev->block_end[BLOCK_BOOT] = 0x3ffff; + } + } else { + dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94; + + /* The block lengths are the same both flash types. */ + dev->block_len[BLOCK_MAIN1] = 0x1c000; + dev->block_len[BLOCK_MAIN2] = 0x00000; + dev->block_len[BLOCK_DATA1] = 0x01000; + dev->block_len[BLOCK_DATA2] = 0x01000; + dev->block_len[BLOCK_BOOT] = 0x02000; + + if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */ + dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */ + dev->block_end[BLOCK_MAIN1] = 0x1ffff; + dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */ + dev->block_end[BLOCK_MAIN2] = 0xfffff; + dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */ + dev->block_end[BLOCK_DATA1] = 0x02fff; + dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */ + dev->block_end[BLOCK_DATA2] = 0x03fff; + dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + dev->block_end[BLOCK_BOOT] = 0x01fff; + } else { /* 28F001BX-T/28F100BX-T */ + dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */ + dev->block_end[BLOCK_MAIN1] = 0x1bfff; + dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */ + dev->block_end[BLOCK_MAIN2] = 0xfffff; + dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ + dev->block_end[BLOCK_DATA1] = 0x1cfff; + dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ + dev->block_end[BLOCK_DATA2] = 0x1dfff; + dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ + dev->block_end[BLOCK_BOOT] = 0x1ffff; + } + } + + intel_flash_add_mappings(dev); + + dev->command = CMD_READ_ARRAY; + dev->status = 0; + + f = nvr_fopen(flash_path, L"rb"); + if (f) { + fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f); + if (dev->block_len[BLOCK_MAIN2]) + fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f); + fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f); + fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f); + fclose(f); + } + + free(flash_name); + free(machine_name); + + if (dev->flags & FLAG_WORD) + dev->flags &= ~FLAG_WORD; + + return dev; +} + + +static void +intel_flash_close(void *p) +{ + FILE *f; + flash_t *dev = (flash_t *)p; + + f = nvr_fopen(flash_path, L"wb"); + fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f); + if (dev->block_len[BLOCK_MAIN2]) + fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f); + fwrite(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f); + fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f); + fclose(f); + + free(dev); +} + + +/* For AMI BIOS'es - Intel 28F001BXT with A16 pin inverted. */ +const device_t intel_flash_bxt_ami_device = +{ + "Intel 28F001BXT/28F002BXT Flash BIOS", + 0, + FLAG_INV_A16, + intel_flash_init, + intel_flash_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +#if defined(DEV_BRANCH) && defined(USE_TC430HX) +const device_t intel_flash_bxtw_ami_device = +{ + "Intel 28F100BXT/28F200BXT Flash BIOS", + 0, + FLAG_INV_A16 | FLAG_WORD, + intel_flash_init, + intel_flash_close, + NULL, + NULL, NULL, NULL, NULL +}; +#endif + + +const device_t intel_flash_bxt_device = +{ + "Intel 28F001BXT/28F002BXT Flash BIOS", + 0, 0, + intel_flash_init, + intel_flash_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t intel_flash_bxb_device = +{ + "Intel 28F001BXB/28F002BXB Flash BIOS", + 0, FLAG_BXB, + intel_flash_init, + intel_flash_close, + NULL, + NULL, NULL, NULL, NULL +}; diff --git a/src/intel_flash.c b/src/intel_flash.c index 7530912f5..59dd16cc4 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -25,7 +25,7 @@ #include "86box.h" #include "device.h" #include "mem.h" -#include "machine/machine.h" +#include "machine.h" #include "timer.h" #include "nvr.h" #include "plat.h" @@ -90,6 +90,11 @@ flash_read(uint32_t addr, void *p) addr &= biosmask; switch (dev->command) { + case 0x00: + case 0x93: + ret = 0xff; + break; + case CMD_READ_ARRAY: default: ret = dev->array[addr]; @@ -129,6 +134,11 @@ flash_readw(uint32_t addr, void *p) ret = *q; if (dev->flags & FLAG_WORD) switch (dev->command) { + case 0x00: + case 0x93: + ret = 0xffff; + break; + case CMD_READ_ARRAY: default: break; @@ -314,6 +324,16 @@ intel_flash_add_mappings(flash_t *dev) } +static void +intel_flash_reset(void *priv) +{ + flash_t *dev = (flash_t *) priv; + + dev->command = CMD_READ_ARRAY; + dev->status = 0; +} + + static void * intel_flash_init(const device_t *info) { @@ -461,11 +481,11 @@ intel_flash_close(void *p) const device_t intel_flash_bxt_ami_device = { "Intel 28F001BXT/28F002BXT Flash BIOS", - 0, + DEVICE_PCI, FLAG_INV_A16, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; @@ -474,11 +494,11 @@ const device_t intel_flash_bxt_ami_device = const device_t intel_flash_bxtw_ami_device = { "Intel 28F100BXT/28F200BXT Flash BIOS", - 0, + DEVICE_PCI, FLAG_INV_A16 | FLAG_WORD, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; #endif @@ -487,10 +507,10 @@ const device_t intel_flash_bxtw_ami_device = const device_t intel_flash_bxt_device = { "Intel 28F001BXT/28F002BXT Flash BIOS", - 0, 0, + DEVICE_PCI, 0, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; @@ -498,9 +518,9 @@ const device_t intel_flash_bxt_device = const device_t intel_flash_bxb_device = { "Intel 28F001BXB/28F002BXB Flash BIOS", - 0, FLAG_BXB, + DEVICE_PCI, FLAG_BXB, intel_flash_init, intel_flash_close, - NULL, + intel_flash_reset, NULL, NULL, NULL, NULL }; diff --git a/src/intel_flash.d b/src/intel_flash.d new file mode 100644 index 000000000..fd1226d2b --- /dev/null +++ b/src/intel_flash.d @@ -0,0 +1,2 @@ +intel_flash.o: intel_flash.c 86box.h device.h mem.h machine/machine.h \ + timer.h cpu_common/cpu.h nvr.h plat.h lang/language.h diff --git a/src/intel_piix - Cópia.c b/src/intel_piix - Cópia.c new file mode 100644 index 000000000..bc7aa2173 --- /dev/null +++ b/src/intel_piix - Cópia.c @@ -0,0 +1,1131 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the Intel PIIX and PIIX3 Xcelerators. + * + * PRD format : + * word 0 - base address + * word 1 - bits 1-15 = byte count, bit 31 = end of transfer + * + * Version: @(#)intel_piix.c 1.0.23 2020/01/24 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include "86box.h" +#include "cdrom.h" +#include "cpu.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" +#include "dma.h" +#include "86box_io.h" +#include "device.h" +#include "apm.h" +#include "keyboard.h" +#include "mem.h" +#include "timer.h" +#include "nvr.h" +#include "pci.h" +#include "pic.h" +#include "port_92.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "hdc_ide_sff8038i.h" +#include "zip.h" +#include "machine.h" +#include "piix.h" + + +#define ACPI_TIMER_FREQ 3579545 + + +typedef struct +{ + uint16_t io_base; + int base_channel; +} ddma_t; + + +typedef struct +{ + int type; + uint8_t cur_readout_reg, + readout_regs[256], + regs[256], regs_ide[256], + regs_usb[256], regs_power[256]; + sff8038i_t *bm[2]; + ddma_t ddma[2]; + nvr_t * nvr; + + struct + { + uint16_t io_base; + } usb; + + struct + { + uint16_t io_base; + } power; +} piix_t; + + +#ifdef ENABLE_PIIX_LOG +int piix_do_log = ENABLE_PIIX_LOG; + + +static void +piix_log(const char *fmt, ...) +{ + va_list ap; + + if (piix_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define piix_log(fmt, ...) +#endif + + +static void +piix_bus_master_handlers(piix_t *dev, uint16_t old_base) +{ + uint16_t base; + + base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); + + sff_bus_master_handlers(dev->bm[0], old_base, base, (dev->regs_ide[0x04] & 1)); + sff_bus_master_handlers(dev->bm[1], old_base + 8, base + 8, (dev->regs_ide[0x04] & 1)); +} + + +static uint8_t +kbc_alias_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = inb(0x61); + + return ret; +} + + +static void +kbc_alias_reg_write(uint16_t addr, uint8_t val, void *p) +{ + outb(0x61, val); +} + + +static void +kbc_alias_update_io_mapping(piix_t *dev) +{ + io_removehandler(0x0063, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_removehandler(0x0065, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_removehandler(0x0067, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + + if (dev->regs[0x4e] & 0x08) { + io_sethandler(0x0063, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_sethandler(0x0065, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_sethandler(0x0067, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + } +} + + +static uint8_t +ddma_reg_read(uint16_t addr, void *p) +{ + ddma_t *dev = (ddma_t *) p; + uint8_t ret = 0xff; + int rel_ch = (addr & 0x30) >> 4; + int ch = dev->base_channel + rel_ch; + int dmab = (ch >= 4) ? 0xc0 : 0x00; + + switch (addr & 0x0f) { + case 0x00: + ret = dma[ch].ac & 0xff; + break; + case 0x01: + ret = (dma[ch].ac >> 8) & 0xff; + break; + case 0x02: + ret = dma[ch].page; + break; + case 0x04: + ret = dma[ch].cc & 0xff; + break; + case 0x05: + ret = (dma[ch].cc >> 8) & 0xff; + break; + case 0x09: + ret = inb(dmab + 0x08); + break; + } + + return ret; +} + + +static void +ddma_reg_write(uint16_t addr, uint8_t val, void *p) +{ + ddma_t *dev = (ddma_t *) p; + int rel_ch = (addr & 0x30) >> 4; + int ch = dev->base_channel + rel_ch; + int page_regs[4] = { 7, 3, 1, 2 }; + int i, dmab = (ch >= 4) ? 0xc0 : 0x00; + + switch (addr & 0x0f) { + case 0x00: + dma[ch].ab = (dma[ch].ab & 0xffff00) | val; + dma[ch].ac = dma[ch].ab; + break; + case 0x01: + dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8); + dma[ch].ac = dma[ch].ab; + break; + case 0x02: + if (ch >= 4) + outb(0x88 + page_regs[rel_ch], val); + else + outb(0x80 + page_regs[rel_ch], val); + break; + case 0x04: + dma[ch].cb = (dma[ch].cb & 0xffff00) | val; + dma[ch].cc = dma[ch].cb; + break; + case 0x05: + dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8); + dma[ch].cc = dma[ch].cb; + break; + case 0x08: + outb(dmab + 0x08, val); + break; + case 0x09: + outb(dmab + 0x09, val); + break; + case 0x0a: + outb(dmab + 0x0a, val); + break; + case 0x0b: + outb(dmab + 0x0b, val); + break; + case 0x0d: + outb(dmab + 0x0d, val); + break; + case 0x0e: + for (i = 0; i < 4; i++) + outb(dmab + 0x0a, i); + break; + case 0x0f: + outb(dmab + 0x0a, (val << 2) | rel_ch); + break; + } +} + + +static void +ddma_update_io_mapping(piix_t *dev, int n) +{ + int base_reg = 0x92 + (n << 1); + + if (dev->ddma[n].io_base != 0x0000) + io_removehandler(dev->usb.io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]); + + dev->ddma[n].io_base = (dev->regs[base_reg] & ~0x3f) | (dev->regs[base_reg + 1] << 8); + + if (dev->ddma[n].io_base != 0x0000) + io_sethandler(dev->ddma[n].io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]); +} + + +static uint8_t +usb_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = 0xff; + + switch (addr & 0x1f) { + case 0x10: case 0x11: case 0x12: case 0x13: + /* Port status */ + ret = 0x00; + break; + } + + return ret; +} + + +static void +usb_reg_write(uint16_t addr, uint8_t val, void *p) +{ +} + + +static void +usb_update_io_mapping(piix_t *dev) +{ + if (dev->usb.io_base != 0x0000) + io_removehandler(dev->usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev); + + dev->usb.io_base = (dev->regs_usb[0x20] & ~0x1f) | (dev->regs_usb[0x21] << 8); + + if ((dev->regs_usb[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->usb.io_base != 0x0000)) + io_sethandler(dev->usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev); +} + + +static uint8_t +power_reg_read(uint16_t addr, void *p) +{ + uint32_t timer; + uint8_t ret = 0xff; + + switch (addr & 0x3f) { + case 0x08: case 0x09: case 0x0a: case 0x0b: + /* ACPI timer */ + timer = (tsc * ACPI_TIMER_FREQ) / machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed; + timer &= 0x00ffffff; + ret = (timer >> (8 * (addr & 3))) & 0xff; + break; + } + + return ret; +} + + +static void +power_reg_write(uint16_t addr, uint8_t val, void *p) +{ +} + + +static void +power_update_io_mapping(piix_t *dev) +{ + if (dev->power.io_base != 0x0000) + io_removehandler(dev->power.io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev); + + dev->power.io_base = (dev->regs_power[0x41] << 8) | (dev->regs_power[0x40] & 0xc0); + + if ((dev->regs_power[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->regs_power[0x80] & 0x01) && (dev->power.io_base != 0x0000)) + io_sethandler(dev->power.io_base, 0x100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev); +} + + +static void +piix_write(int func, int addr, uint8_t val, void *priv) +{ + piix_t *dev = (piix_t *) priv; + int type = dev->type & 0xff; + uint8_t valxor; + uint16_t old_base; + + if ((func > 0) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ + return; + + if ((func > 1) && ((type & 0xff) < 3)) /* PIIX has no USB part. */ + return; + + if ((func > 2) && ((type & 0xff) < 4)) /* PIIX and PIIX3 have no Power Management part. */ + return; + + if (func > 3) + return; + + old_base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); + + pclog("PIIX function %i write: %02X to %02X\n", func, val, addr); + + if (func == 3) { /* Power Management */ + /* Read-only addresses */ + if ((addr < 4) || (addr == 5) || (addr == 6) || ((addr >= 8) && (addr < 0x3c)) || + ((addr >= 0x3c) && (addr < 0x40)) || (addr == 0x53) || + ((addr >= 0x81) && (addr < 0x90)) || ((addr >= 0x94) && (addr < 0xd2)) || + (addr > 0xd6)) + return; + + switch (addr) { + case 0x04: + dev->regs_power[0x04] = val & 0x01; + power_update_io_mapping(dev); + break; + case 0x07: + dev->regs_power[0x07] = val & 0x0e; + break; + + case 0x3c: + dev->regs_power[0x3c] = val; + break; + + case 0x40: + dev->regs_power[0x20] = (val & ~0x3f) | 1; + power_update_io_mapping(dev); + break; + case 0x41: + dev->regs_power[0x21] = val; + power_update_io_mapping(dev); + break; + + case 0x80: + dev->regs_power[0x80] = val & 0x01; + power_update_io_mapping(dev); + break; + + default: + dev->regs_power[addr] = val; + break; + } + } else if (func == 2) { /* USB */ + /* Read-only addresses */ + if ((addr < 4) || (addr == 5) || (addr == 6) || ((addr >= 8) && (addr < 0xd)) || + ((addr >= 0xe) && (addr < 0x20)) || ((addr >= 0x22) && (addr < 0x3c)) || + ((addr >= 0x3e) && (addr < 0x40)) || ((addr >= 0x42) && (addr < 0x44)) || + ((addr >= 0x46) && (addr < 0xc0)) || (addr >= 0xc2)) + return; + + switch (addr) { + case 0x04: + dev->regs_usb[0x04] = val & 0x97; + usb_update_io_mapping(dev); + break; + case 0x07: + dev->regs_usb[0x07] = val & 0x7f; + break; + + case 0x20: + dev->regs_usb[0x20] = (val & ~0x1f) | 1; + usb_update_io_mapping(dev); + break; + case 0x21: + dev->regs_usb[0x21] = val; + usb_update_io_mapping(dev); + break; + + case 0xff: + if (type >= 4) { + dev->regs_usb[addr] = val & 0x10; + nvr_at_handler(0, 0x0070, dev->nvr); + if ((dev->regs[0xcb] & 0x01) && (dev->regs_usb[0xff] & 0x10)) + nvr_at_handler(1, 0x0070, dev->nvr); + } + break; + + default: + dev->regs_usb[addr] = val; + break; + } + } else if (func == 1) { /* IDE */ + piix_log("PIIX IDE write: %02X %02X\n", addr, val); + valxor = val ^ dev->regs_ide[addr]; + + switch (addr) { + case 0x04: + pclog("04 write: %02X\n", val); + dev->regs_ide[0x04] = (val & 5); + if (valxor & 0x01) { + ide_pri_disable(); + ide_sec_disable(); + if (val & 0x01) { + // pclog("04: I/O enabled\n"); + if (dev->regs_ide[0x41] & 0x80) { + // pclog("04: PRI enabled\n"); + ide_pri_enable(); + } + if (dev->regs_ide[0x43] & 0x80) { + // pclog("04: SEC enabled\n"); + ide_sec_enable(); + } + } else + // pclog("04: I/O disabled\n"); + + piix_bus_master_handlers(dev, old_base); + } + break; + case 0x07: + dev->regs_ide[0x07] = (dev->regs_ide[0x07] & 0xf9) | (val & 0x06); + if (val & 0x20) + dev->regs_ide[0x07] &= 0xdf; + if (val & 0x10) + dev->regs_ide[0x07] &= 0xef; + if (val & 0x08) + dev->regs_ide[0x07] &= 0xf7; + if (val & 0x04) + dev->regs_ide[0x07] &= 0xfb; + break; + case 0x0d: + dev->regs_ide[0x0d] = val & 0xf0; + break; + + case 0x20: + dev->regs_ide[0x20] = (val & 0xf0) | 1; + if (valxor) + piix_bus_master_handlers(dev, old_base); + break; + case 0x21: + dev->regs_ide[0x21] = val; + if (valxor) + piix_bus_master_handlers(dev, old_base); + break; + + case 0x40: + dev->regs_ide[0x40] = val; + break; + case 0x41: + dev->regs_ide[0x41] = val & ((type >= 3) ? 0xf3 : 0xb3); + if (valxor & 0x80) { + ide_pri_disable(); + if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) + ide_pri_enable(); + } + break; + case 0x42: + dev->regs_ide[0x42] = val; + break; + case 0x43: + dev->regs_ide[0x43] = val & ((type >= 3) ? 0xf3 : 0xb3); + if (valxor & 0x80) { + ide_sec_disable(); + if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) + ide_sec_enable(); + } + break; + case 0x44: + if (type >= 3) dev->regs_ide[0x44] = val; + break; + case 0x48: + case 0x4a: case 0x4b: + if (type >= 4) dev->regs_ide[addr] = val; + break; + } + } else { + piix_log("PIIX writing value %02X to register %02X\n", val, addr); + valxor = val ^ dev->regs[addr]; + + if ((addr >= 0x0f) && (addr < 0x4c)) + return; + + if ((addr >= 0xa0) && (addr < 0xb0) && (type == 4)) + return; + + switch (addr) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0e: + return; + + case 0x07: + dev->regs[0x07] = (dev->regs[0x07] & 0xf9) | (val & 0x06); + if ((val & 0x40) && (type >= 3)) + dev->regs[0x07] &= 0xbf; + if (val & 0x20) + dev->regs[0x07] &= 0xdf; + if (val & 0x10) + dev->regs[0x07] &= 0xef; + if (val & 0x08) + dev->regs[0x07] &= 0xf7; + if (val & 0x04) + dev->regs[0x07] &= 0xfb; + return; + break; + case 0x4c: + if (valxor) { + if (type >= 3) + dma_alias_remove(); + else + dma_alias_remove_piix(); + if (!(val & 0x80)) + dma_alias_set(); + } + break; + case 0x4e: + keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); + if (type >= 4) + kbc_alias_update_io_mapping(dev); + break; + case 0x60: + piix_log("Set IRQ routing: INT A -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + piix_log("Set IRQ routing: INT B -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x62: + piix_log("Set IRQ routing: INT C -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x63: + piix_log("Set IRQ routing: INT D -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; + case 0x6a: + if (dev->type == 3) + dev->regs[addr] = (val & 0xFD) | (dev->regs[addr] | 2); + else + dev->regs[addr] = (val & 0xFC) | (dev->regs[addr] | 3); + return; + case 0x70: + piix_log("Set MIRQ routing: MIRQ0 -> %02X\n", val); + if (type < 4) { + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ0, val & 0xf); + } + break; + piix_log("MIRQ0 is %s\n", (val & 0x20) ? "disabled" : "enabled"); + case 0x71: + if (type < 3) { + piix_log("Set MIRQ routing: MIRQ1 -> %02X\n", val); + if (val & 0x80) + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + else + pci_set_mirq_routing(PCI_MIRQ1, val & 0xf); + } + break; + case 0x92: case 0x93: case 0x94: case 0x95: + if (type == 4) + ddma_update_io_mapping(dev, (addr >> 2) & 1); + break; + case 0xcb: + if (type == 4) { + nvr_at_handler(0, 0x0070, dev->nvr); + nvr_at_handler(0, 0x0072, dev->nvr); + + if ((val & 0x01) && (dev->regs_usb[0xff] & 0x10)) + nvr_at_handler(1, 0x0070, dev->nvr); + if (val & 0x04) + nvr_at_handler(1, 0x0072, dev->nvr); + + nvr_wp_set(!!(val & 0x08), 0, dev->nvr); + nvr_wp_set(!!(val & 0x10), 1, dev->nvr); + } + break; + } + + dev->regs[addr] = val; + } +} + + +static uint8_t +piix_read(int func, int addr, void *priv) +{ + piix_t *dev = (piix_t *) priv; + int type = dev->type & 0xff; + int ret = 0xff, ignore = 0; + + if ((func > 0) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ + ignore = 1; + + if ((func > 1) && ((type & 0xff) < 3)) /* PIIX has no USB part. */ + ignore = 1; + + if ((func > 2) && ((type & 0xff) < 4)) /* PIIX and PIIX3 have no Power Management part. */ + ignore = 1; + + if (func > 3) + ignore = 1; + + if (!ignore) { + ret = 0x00; + + if (func == 3) /* Power Management */ + ret = dev->regs_power[addr]; + else if (func == 2) /* USB */ + ret = dev->regs_usb[addr]; + else if (func == 1) switch (addr) { /* IDE */ + case 0x05: case 0x22: case 0x23: + ret = 0x00; + break; + case 0x06: + ret = 0x80; + break; + default: + ret = dev->regs_ide[addr]; + break; + } else if (func == 0) switch (addr) { + case 0x04: + ret = (dev->regs[addr] & 0x80) | ((dev->type & 0x100) ? 0x0f : 0x07); + break; + case 0x05: + if (type >= 3) + ret = dev->regs[addr] & 1; + else + ret = 0; + break; + case 0x06: + ret = dev->regs[addr] & 0x80; + break; + case 0x07: + if (type >= 3) + ret = dev->regs[addr]; + else { + if (dev->type & 0x100) + ret = dev->regs[addr] & 0x02; + else + ret = dev->regs[addr] & 0x3E; + } + break; + caer 0x4e: + ret = (dev->regs[addr] & 0xef) | keyboard_at_get_mouse_scan(); + case 0x60: case 0x61: case 0x62: cae 0x63: + ret = dev->regs[addr] & 0x8f; + break; + case 0x69: + ret = dev->regs[addr] & 0xfe; + break; + case 0x6a: + if (dev->type == 3) + ret = dev->regs[addr] & 0xD1; + else + ret = dev->regs[addr] & 0x07; + break; + case 0x6b: + if (dev->type == 3) + ret = dev->regs[addr] & 0x80; + else + ret = 0x00; + break; + case 0x70: + if (type < 4) + ret = dev->regs[addr] & ((type >= 3) ? 0xef : 0xcf); + else + ret = 0x00; + break; + case 0x71: + if (type < 3) + ret = dev->regs[addr] & 0xcf; + else + ret = 0x00; + break; + case 0x76: case 0x77: + if (dev->type == 3) + ret = dev->regs[addr] & 0x87; + else + ret = dev->regs[addr] & 0x8F; + break; + case 0x80: + if (dev->type == 3) + ret = dev->regs[addr] & 0x7f; + else if (dev->type == 1) + ret = 0x00; + break; + case 0x82: + if (dev->type == 3) + ret = dev->regs[addr] & 0x0f; + else + ret = 0x00; + break; + case 0xa0: + ret = dev->regs[addr] & 0x1f; + break; + case 0xa3: + if (dev->type == 3) + ret = dev->regs[addr] & 1; + else + ret = 0x00; + break; + case 0xa7: + if (dev->type == 3) + ret = dev->regs[addr]; + else + ret = dev->regs[addr] & 0xef; + break; + case 0xab: + if (dev->type == 3) + ret = dev->regs[addr]; + else + ret = dev->regs[addr] & 0xfe; + break; + default: + ret = dev->regs[addr]; + break; + } + } + + pclog("PIIX function %i read: %02X from %02X\n", func, ret, addr); + + return ret; +} + + +static void +board_write(uint16_t port, uint8_t val, void *priv) +{ + piix_t *dev = (piix_t *) priv; + + // pclog("board write %02X at %04X\n", val, port); + + if (port == 0x00e0) + dev->cur_readout_reg = val; + else if (port == 0x00e1) + dev->readout_regs[dev->cur_readout_reg] = val; +} + + +static uint8_t +board_read(uint16_t port, void *priv) +{ + piix_t *dev = (piix_t *) priv; + uint8_t ret = 0xff; + + if (port == 0x00e0) + ret = dev->cur_readout_reg; + else if (port == 0x00e1) + ret = dev->readout_regs[dev->cur_readout_reg]; + + // pclog("board read %02X at %04X\n", ret, port); + + return ret; +} + + +static void +piix_reset_hard(void *priv) +{ + piix_t *piix = (piix_t *) priv; + int type = (piix->type & 0xff); + + uint16_t old_base = (piix->regs_ide[0x20] & 0xf0) | (piix->regs_ide[0x21] << 8); + + if (!(piix->type & 0x100)) { /* PB640's PIIX has no IDE part. */ + sff_bus_master_reset(piix->bm[0], old_base); + sff_bus_master_reset(piix->bm[1], old_base + 8); + + if (type == 4) { + sff_set_irq_mode(piix->bm[0], 0); + sff_set_irq_mode(piix->bm[1], 0); + } + + pclog("piix_reset_hard()\n"); + ide_pri_disable(); + ide_sec_disable(); + } + + if (type == 4) { + nvr_at_handler(0, 0x0072, piix->nvr); + nvr_wp_set(0, 0, piix->nvr); + nvr_wp_set(0, 1, piix->nvr); + } + + memset(piix->regs, 0, 256); + memset(piix->regs_ide, 0, 256); + memset(piix->regs_usb, 0, 256); + memset(piix->regs_power, 0, 256); + + piix->regs[0x00] = 0x86; piix->regs[0x01] = 0x80; /*Intel*/ + if (type == 4) { + piix->regs[0x02] = 0x10; piix->regs[0x03] = 0x71; /*82371AB (PIIX4)*/ + } else if (type == 3) { + piix->regs[0x02] = 0x00; piix->regs[0x03] = 0x70; /*82371SB (PIIX3)*/ + } else { + piix->regs[0x02] = 0x2e; piix->regs[0x03] = 0x12; /*82371FB (PIIX)*/ + } + if (piix->type & 0x100) + piix->regs[0x04] = 0x06; + else + piix->regs[0x04] = 0x07; + piix->regs[0x05] = 0x00; + piix->regs[0x06] = 0x80; piix->regs[0x07] = 0x02; + if (piix->type & 0x100) + piix->regs[0x08] = 0x02; /*A0 stepping*/ + else + piix->regs[0x08] = 0x00; /*A0 stepping*/ + piix->regs[0x09] = 0x00; piix->regs[0x0a] = 0x01; piix->regs[0x0b] = 0x06; + if (piix->type & 0x100) + piix->regs[0x0e] = 0x00; /*Single-function device*/ + else + piix->regs[0x0e] = 0x80; /*Multi-function device*/ + piix->regs[0x4c] = 0x4d; + piix->regs[0x4e] = 0x03; + if (type >= 3) + piix->regs[0x4f] = 0x00; + piix->regs[0x60] = piix->regs[0x61] = piix->regs[0x62] = piix->regs[0x63] = 0x80; + if (type == 4) + piix->regs[0x64] = 0x10; + piix->regs[0x69] = 0x02; + if (type < 4) + piix->regs[0x70] = 0xc0; + if (type < 3) + piix->regs[0x71] = 0xc0; + piix->regs[0x76] = piix->regs[0x77] = 0x0c; + piix->regs[0x78] = 0x02; piix->regs[0x79] = 0x00; + if (type == 3) { + piix->regs[0x80] = piix->regs[0x82] = 0x00; + } + piix->regs[0xa0] = 0x08; + piix->regs[0xa2] = piix->regs[0xa3] = 0x00; + piix->regs[0xa4] = piix->regs[0xa5] = piix->regs[0xa6] = piix->regs[0xa7] = 0x00; + piix->regs[0xa8] = 0x0f; + piix->regs[0xaa] = piix->regs[0xab] = 0x00; + piix->regs[0xac] = 0x00; + piix->regs[0xae] = 0x00; + if (type == 4) + piix->regs[0xcb] = 0x21; + + piix->regs_ide[0x00] = 0x86; piix->regs_ide[0x01] = 0x80; /*Intel*/ + if (type == 4) { + piix->regs_ide[0x02] = 0x11; piix->regs_ide[0x03] = 0x71; /*82371AB (PIIX4)*/ + } else if (type == 3) { + piix->regs_ide[0x02] = 0x10; piix->regs_ide[0x03] = 0x70; /*82371SB (PIIX3)*/ + } else { + piix->regs_ide[0x02] = 0x30; piix->regs_ide[0x03] = 0x12; /*82371FB (PIIX)*/ + } + piix->regs_ide[0x04] = 0x00; piix->regs_ide[0x05] = 0x00; + piix->regs_ide[0x06] = 0x80; piix->regs_ide[0x07] = 0x02; + piix->regs_ide[0x08] = 0x00; + piix->regs_ide[0x09] = 0x80; piix->regs_ide[0x0a] = 0x01; piix->regs_ide[0x0b] = 0x01; + piix->regs_ide[0x0d] = 0x00; + piix->regs_ide[0x0e] = 0x00; + piix->regs_ide[0x20] = 0x01; piix->regs_ide[0x21] = piix->regs_ide[0x22] = piix->regs_ide[0x23] = 0x00; /*Bus master interface base address*/ + piix->regs_ide[0x40] = piix->regs_ide[0x42] = 0x00; + piix->regs_ide[0x41] = piix->regs_ide[0x43] = 0x00; + if (type >= 3) + piix->regs_ide[0x44] = 0x00; + if (type == 4) { + piix->regs_ide[0x48] = piix->regs_ide[0x4a] = + piix->regs_ide[0x4b] = 0x00; + } + + if (type >= 3) { + piix->regs_usb[0x00] = 0x86; piix->regs_usb[0x01] = 0x80; /*Intel*/ + if (type == 4) { + piix->regs_usb[0x02] = 0x12; piix->regs_usb[0x03] = 0x71; /*82371AB (PIIX4)*/ + } else { + piix->regs_usb[0x02] = 0x20; piix->regs_usb[0x03] = 0x70; /*82371SB (PIIX3)*/ + } + piix->regs_usb[0x04] = 0x00; piix->regs_usb[0x05] = 0x00; + piix->regs_usb[0x06] = 0x00; piix->regs_usb[0x07] = 0x02; + piix->regs_usb[0x0a] = 0x03; + piix->regs_usb[0x0b] = 0x0c; + piix->regs_usb[0x0d] = 0x16; + piix->regs_usb[0x20] = 0x01; + piix->regs_usb[0x21] = 0x03; + piix->regs_usb[0x3d] = 0x04; + + piix->regs_usb[0x60] = 0x10; + piix->regs_usb[0xc1] = 0x20; + } + + if (type == 4) { + piix->regs_power[0x00] = 0x86; piix->regs_power[0x01] = 0x80; /*Intel*/ + piix->regs_power[0x02] = 0x13; piix->regs_power[0x03] = 0x71; /*82371AB (PIIX4)*/ + piix->regs_power[0x04] = 0x00; piix->regs_power[0x05] = 0x00; + piix->regs_power[0x06] = 0x80; piix->regs_power[0x07] = 0x02; + piix->regs_power[0x08] = 0x00; /*Initial Stepping=00h*/ + piix->regs_power[0x0a] = 0x80; + piix->regs_power[0x0b] = 0x06; + piix->regs_power[0x3d] = 0x01; + piix->regs_power[0x40] = 0x01; + piix->regs_power[0x90] = 0x01; + } + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + + if (type < 4) + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + if (type < 3) + pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); +} + + +static void +piix_close(void *p) +{ + piix_t *piix = (piix_t *)p; + + free(piix); +} + + +static void +*piix_init(const device_t *info) +{ + piix_t *piix = (piix_t *) malloc(sizeof(piix_t)); + int type; + memset(piix, 0, sizeof(piix_t)); + + pci_add_card(7, piix_read, piix_write, piix); + + piix->type = info->local; + type = (piix->type & 0xff); + + device_add(&apm_device); + + if (!(piix->type & 0x100)) { /* PB640's PIIX has no IDE part. */ + piix->bm[0] = device_add_inst(&sff8038i_device, 1); + piix->bm[1] = device_add_inst(&sff8038i_device, 2); + } + + if (type == 4) + piix->nvr = device_add(&piix4_nvr_device); + + piix_reset_hard(piix); + + device_add(&port_92_pci_device); + + dma_alias_set(); + + if (type < 4) + pci_enable_mirq(0); + if (type < 3) + pci_enable_mirq(1); + + piix->readout_regs[1] = 0x40; + + /* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined): + + Bit 6: 1 = can boot, 0 = no; + Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, 10 = 3.0, 11 = 1.5); + Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, 10 = 60 MHz, 11 = ????): + Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, 0100 = 150 MHz, 0110 = ??? MHz; + 0001 = 100 MHz, 0011 = 133 MHz, 0101 = 120 MHz, 0111 = ??? MHz; + 1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz; + 1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */ + + switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].pci_speed) { + case 20000000: + piix->readout_regs[1] |= 0x30; + break; + case 25000000: + default: + piix->readout_regs[1] |= 0x00; + break; + case 30000000: + piix->readout_regs[1] |= 0x20; + break; + case 33333333: + piix->readout_regs[1] |= 0x10; + break; + } + + switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) { + case 75000000: + piix->readout_regs[1] |= 0x82; /* 50 MHz * 1.5 multiplier */ + break; + case 90000000: + piix->readout_regs[1] |= 0x82; /* 60 MHz * 1.5 multiplier */ + break; + case 100000000: + if ((piix->readout_regs[1] & 0x30) == 0x10) + piix->readout_regs[1] |= 0x82; /* 66 MHz * 1.5 multiplier */ + else + piix->readout_regs[1] |= 0x02; /* 50 MHz * 2.0 multiplier */ + break; + case 12000000: + piix->readout_regs[1] |= 0x02; /* 60 MHz * 2.0 multiplier */ + break; + case 125000000: + piix->readout_regs[1] |= 0x00; /* 50 MHz * 2.5 multiplier */ + break; + case 133333333: + piix->readout_regs[1] |= 0x02; /* 66 MHz * 2.0 multiplier */ + break; + case 150000000: + if ((piix->readout_regs[1] & 0x30) == 0x20) + piix->readout_regs[1] |= 0x00; /* 60 MHz * 2.5 multiplier */ + else + piix->readout_regs[1] |= 0x80; /* 50 MHz * 3.0 multiplier */ + break; + case 166666666: + piix->readout_regs[1] |= 0x00; /* 66 MHz * 2.5 multiplier */ + break; + case 180000000: + piix->readout_regs[1] |= 0x80; /* 60 MHz * 3.0 multiplier */ + break; + case 200000000: + piix->readout_regs[1] |= 0x80; /* 66 MHz * 3.0 multiplier */ + break; + } + + io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, piix); + io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, piix); + + return piix; +} + + +const device_t piix_device = +{ + "Intel 82371FB (PIIX)", + DEVICE_PCI, + 1, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const device_t piix_pb640_device = +{ + "Intel 82371FB (PIIX) (PB640)", + DEVICE_PCI, + 0x101, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const device_t piix3_device = +{ + "Intel 82371SB (PIIX3)", + DEVICE_PCI, + 3, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const device_t piix4_device = +{ + "Intel 82371AB (PIIX4)", + DEVICE_PCI, + 4, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/intel_piix.c b/src/intel_piix.c index d5fdfc36f..dd504cf25 100644 --- a/src/intel_piix.c +++ b/src/intel_piix.c @@ -10,13 +10,13 @@ * word 0 - base address * word 1 - bits 1-15 = byte count, bit 31 = end of transfer * - * Version: @(#)intel_piix.c 1.0.22 2018/10/31 + * Version: @(#)intel_piix.c 1.0.23 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ #include #include @@ -26,34 +26,89 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cdrom/cdrom.h" -#include "cpu/cpu.h" -#include "scsi/scsi_device.h" -#include "scsi/scsi_cdrom.h" +#include "cdrom.h" +#include "cpu.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" #include "dma.h" -#include "io.h" +#include "86box_io.h" #include "device.h" #include "apm.h" #include "keyboard.h" #include "mem.h" +#include "timer.h" +#include "nvr.h" #include "pci.h" #include "pic.h" #include "port_92.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/hdc_ide_sff8038i.h" -#include "disk/zip.h" -#include "machine/machine.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "hdc_ide_sff8038i.h" +#include "zip.h" +#include "machine.h" #include "piix.h" +#define ACPI_TIMER_FREQ 3579545 +#define PM_FREQ ACPI_TIMER_FREQ + +#define RSM_STS (1 << 15) +#define PWRBTN_STS (1 << 8) + +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) + +#define SCI_EN (1 << 0) +#define SUS_EN (1 << 13) + +#define ACPI_ENABLE 0xf1 +#define ACPI_DISABLE 0xf0 + + +typedef struct +{ + uint16_t io_base; + int base_channel; +} ddma_t; + + +typedef struct +{ + uint8_t gpireg[3], gporeg[4]; + uint16_t pmsts, pmen, + pmcntrl; + uint32_t glbctl; + uint64_t tmr_overflow_time; + int timer_index; +} power_t; + + +typedef struct +{ + uint8_t stat, ctl, cmd, addr, + data0, data1, + index, + data[32]; +} smbus_t; + + typedef struct { - int type; uint8_t cur_readout_reg, - readout_regs[256], - regs[256], regs_ide[256]; + type, func_shift, + max_func, pci_slot, + regs[4][256], + readout_regs[256], board_config[2]; + uint16_t func0_id, + usb_io_base, power_io_base, + smbus_io_base; sff8038i_t *bm[2]; + ddma_t ddma[2]; + power_t power; + smbus_t smbus; + nvr_t * nvr; } piix_t; @@ -77,15 +132,355 @@ piix_log(const char *fmt, ...) #endif -static void -piix_bus_master_handlers(piix_t *dev, uint16_t old_base) +static +void do_irq(piix_t *dev, int func, int level) { - uint16_t base; + if ((dev == NULL) || (func > dev->max_func) /*|| + (dev->regs[func][0x3d] < PCI_INTA) || (dev->regs[func][0x3d] < PCI_INTD)*/) + return; - base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); + if (level) { + // pci_set_irq(dev->pci_slot, dev->regs[func][0x3d]); + picintlevel(1 << 9); + piix_log("Raising IRQ...\n"); + } else { + // pci_clear_irq(dev->pci_slot, dev->regs[func][0x3d]); + picintc(1 << 9); + piix_log("Lowering IRQ...\n"); + } +} - sff_bus_master_handlers(dev->bm[0], old_base, base, (dev->regs_ide[0x04] & 1)); - sff_bus_master_handlers(dev->bm[1], old_base + 8, base + 8, (dev->regs_ide[0x04] & 1)); + +static void +piix_ide_legacy_handlers(piix_t *dev, int bus) +{ + if (bus & 0x01) { + ide_pri_disable(); + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) + ide_pri_enable(); + } + + if (bus & 0x02) { + ide_sec_disable(); + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) + ide_sec_enable(); + } +} + + +static void +piix_ide_bm_handlers(piix_t *dev) +{ + uint16_t base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8); + + sff_bus_master_handler(dev->bm[0], (dev->regs[1][0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], (dev->regs[1][0x04] & 1), base + 8); +} + + +static uint8_t +kbc_alias_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = inb(0x61); + + return ret; +} + + +static void +kbc_alias_reg_write(uint16_t addr, uint8_t val, void *p) +{ + outb(0x61, val); +} + + +static void +kbc_alias_update_io_mapping(piix_t *dev) +{ + io_removehandler(0x0063, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_removehandler(0x0065, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_removehandler(0x0067, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + + if (dev->regs[0][0x4e] & 0x08) { + io_sethandler(0x0063, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_sethandler(0x0065, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + io_sethandler(0x0067, 1, kbc_alias_reg_read, NULL, NULL, kbc_alias_reg_write, NULL, NULL, dev); + } +} + + +static uint8_t +ddma_reg_read(uint16_t addr, void *p) +{ + ddma_t *dev = (ddma_t *) p; + uint8_t ret = 0xff; + int rel_ch = (addr & 0x30) >> 4; + int ch = dev->base_channel + rel_ch; + int dmab = (ch >= 4) ? 0xc0 : 0x00; + + switch (addr & 0x0f) { + case 0x00: + ret = dma[ch].ac & 0xff; + break; + case 0x01: + ret = (dma[ch].ac >> 8) & 0xff; + break; + case 0x02: + ret = dma[ch].page; + break; + case 0x04: + ret = dma[ch].cc & 0xff; + break; + case 0x05: + ret = (dma[ch].cc >> 8) & 0xff; + break; + case 0x09: + ret = inb(dmab + 0x08); + break; + } + + return ret; +} + + +static void +ddma_reg_write(uint16_t addr, uint8_t val, void *p) +{ + ddma_t *dev = (ddma_t *) p; + int rel_ch = (addr & 0x30) >> 4; + int ch = dev->base_channel + rel_ch; + int page_regs[4] = { 7, 3, 1, 2 }; + int i, dmab = (ch >= 4) ? 0xc0 : 0x00; + + switch (addr & 0x0f) { + case 0x00: + dma[ch].ab = (dma[ch].ab & 0xffff00) | val; + dma[ch].ac = dma[ch].ab; + break; + case 0x01: + dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8); + dma[ch].ac = dma[ch].ab; + break; + case 0x02: + if (ch >= 4) + outb(0x88 + page_regs[rel_ch], val); + else + outb(0x80 + page_regs[rel_ch], val); + break; + case 0x04: + dma[ch].cb = (dma[ch].cb & 0xffff00) | val; + dma[ch].cc = dma[ch].cb; + break; + case 0x05: + dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8); + dma[ch].cc = dma[ch].cb; + break; + case 0x08: + outb(dmab + 0x08, val); + break; + case 0x09: + outb(dmab + 0x09, val); + break; + case 0x0a: + outb(dmab + 0x0a, val); + break; + case 0x0b: + outb(dmab + 0x0b, val); + break; + case 0x0d: + outb(dmab + 0x0d, val); + break; + case 0x0e: + for (i = 0; i < 4; i++) + outb(dmab + 0x0a, i); + break; + case 0x0f: + outb(dmab + 0x0a, (val << 2) | rel_ch); + break; + } +} + + +static void +ddma_update_io_mapping(piix_t *dev, int n) +{ + int base_reg = 0x92 + (n << 1); + + if (dev->ddma[n].io_base != 0x0000) + io_removehandler(dev->usb_io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]); + + dev->ddma[n].io_base = (dev->regs[0][base_reg] & ~0x3f) | (dev->regs[0][base_reg + 1] << 8); + + if (dev->ddma[n].io_base != 0x0000) + io_sethandler(dev->ddma[n].io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]); +} + + +static uint8_t +usb_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = 0xff; + + switch (addr & 0x1f) { + case 0x10: case 0x11: case 0x12: case 0x13: + /* Port status */ + ret = 0x00; + break; + } + + return ret; +} + + +static void +usb_reg_write(uint16_t addr, uint8_t val, void *p) +{ +} + + +static void +usb_update_io_mapping(piix_t *dev) +{ + if (dev->usb_io_base != 0x0000) + io_removehandler(dev->usb_io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev); + + dev->usb_io_base = (dev->regs[2][0x20] & ~0x1f) | (dev->regs[2][0x21] << 8); + + if ((dev->regs[2][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->usb_io_base != 0x0000)) + io_sethandler(dev->usb_io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev); +} + + +static uint32_t +power_reg_readl(uint16_t addr, void *p) +{ + piix_t *dev = (piix_t *) p; + uint32_t timer; + uint32_t ret = 0xffffffff; + + switch (addr & 0x3c) { + case 0x08: + /* ACPI timer */ + timer = (tsc * ACPI_TIMER_FREQ) / machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed; + timer &= 0x00ffffff; + ret = timer; + break; + } + + // pclog("ACPI: Read L %08X from %04X\n", ret, addr); + + return ret; +} + + +static uint16_t +power_reg_readw(uint16_t addr, void *p) +{ + piix_t *dev = (piix_t *) p; + uint16_t ret = 0xffff; + uint32_t ret32; + + switch (addr & 0x3c) { + case 0x00: + break; + default: + ret32 = power_reg_readl(addr, p); + if (addr & 0x02) + ret = (ret32 >> 16) & 0xffff; + else + ret = ret32 & 0xffff; + break; + } + + // pclog("ACPI: Read W %08X from %04X\n", ret, addr); + + return ret; +} + + +static uint8_t +power_reg_read(uint16_t addr, void *p) +{ + piix_t *dev = (piix_t *) p; + uint32_t timer; + uint8_t ret = 0xff; + uint16_t ret16; + + switch (addr & 0x3f) { + case 0x30: case 0x31: case 0x32: + ret = dev->power.gporeg[addr & 0x03]; + // pclog("ACPI: Read B %02X from GPIREG %01X\n", ret, addr & 0x03); + break; + case 0x34: case 0x35: case 0x36: case 0x37: + ret = dev->power.gporeg[addr & 0x03]; + // pclog("ACPI: Read B %02X from GPOREG %01X\n", ret, addr & 0x03); + break; + default: + ret16 = power_reg_readw(addr, p); + if (addr & 0x01) + ret = (ret16 >> 8) & 0xff; + else + ret = ret16 & 0xff; + break; + } + + return ret; +} + + +static void +power_reg_write(uint16_t addr, uint8_t val, void *p) +{ + piix_t *dev = (piix_t *) p; + + // pclog("ACPI: Write %02X to %04X\n", val, addr); + + switch (addr & 0x3f) { + case 0x34: case 0x35: case 0x36: case 0x37: + dev->power.gporeg[addr & 0x03] = val; + break; + } +} + + +static void +power_update_io_mapping(piix_t *dev) +{ + if (dev->power_io_base != 0x0000) + io_removehandler(dev->power_io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev); + + dev->power_io_base = (dev->regs[3][0x41] << 8) | (dev->regs[3][0x40] & 0xc0); + + if ((dev->regs[3][0x80] & 0x01) && (dev->power_io_base != 0x0000)) + io_sethandler(dev->power_io_base, 0x40, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, dev); +} + + +static uint8_t +smbus_reg_read(uint16_t addr, void *p) +{ + uint8_t ret = 0x00; + + return ret; +} + + +static void +smbus_reg_write(uint16_t addr, uint8_t val, void *p) +{ +} + + +static void +smbus_update_io_mapping(piix_t *dev) +{ + if (dev->smbus_io_base != 0x0000) + io_removehandler(dev->smbus_io_base, 0x10, smbus_reg_read, NULL, NULL, smbus_reg_write, NULL, NULL, dev); + + dev->smbus_io_base = (dev->regs[3][0x91] << 8) | (dev->regs[3][0x90] & 0xf0); + + if ((dev->regs[3][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->regs[3][0xd2] & 0x01) && (dev->smbus_io_base != 0x0000)) + io_sethandler(dev->smbus_io_base, 0x10, smbus_reg_read, NULL, NULL, smbus_reg_write, NULL, NULL, dev); } @@ -93,161 +488,387 @@ static void piix_write(int func, int addr, uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; - uint8_t valxor; - uint16_t old_base; + uint8_t *fregs; - if ((func == 1) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ + /* Return on unsupported function. */ + if (func > dev->max_func) return; - if (func > 1) - return; + // pclog("PIIX function %i write: %02X to %02X\n", func, val, addr); + fregs = (uint8_t *) dev->regs[func]; - old_base = (dev->regs_ide[0x20] & 0xf0) | (dev->regs_ide[0x21] << 8); - - if (func == 1) { /*IDE*/ - piix_log("PIIX IDE write: %02X %02X\n", addr, val); - valxor = val ^ dev->regs_ide[addr]; - - switch (addr) { - case 0x04: - dev->regs_ide[0x04] = (val & 5) | 2; - if (valxor & 0x01) { - ide_pri_disable(); - ide_sec_disable(); - if (val & 0x01) { - if (dev->regs_ide[0x41] & 0x80) - ide_pri_enable(); - if (dev->regs_ide[0x43] & 0x80) - ide_sec_enable(); + if (func == 0) switch (addr) { + case 0x04: + fregs[0x04] = (val & 0x08) | 0x07; + break; + case 0x05: + if (dev->type > 1) + fregs[0x05] = (val & 0x01); + break; + case 0x07: + if ((val & 0x40) && (dev->type > 1)) + fregs[0x07] &= 0xbf; + if (val & 0x20) + fregs[0x07] &= 0xdf; + if (val & 0x10) + fregs[0x07] &= 0xef; + if (val & 0x08) + fregs[0x07] &= 0xf7; + if (val & 0x04) + fregs[0x07] &= 0xfb; + break; + case 0x4c: + fregs[0x4c] = val; + if (val & 0x80) { + if (dev->type > 1) + dma_alias_remove(); + else + dma_alias_remove_piix(); + } else { + if (dev->type > 1) + dma_alias_set(); + else + dma_alias_set_piix(); + } + break; + case 0x4e: + fregs[0x4e] = val; + keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); + if (dev->type >= 4) + kbc_alias_update_io_mapping(dev); + break; + case 0x4f: + if (dev->type > 3) + fregs[0x4f] = val & 0x07; + else if (dev->type == 3) + fregs[0x4f] = val & 0x01; + break; + case 0x60: case 0x61: case 0x62: case 0x63: + piix_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x03), val); + fregs[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr & 0x03), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr & 0x03), val & 0xf); + break; + case 0x64: + if (dev->type > 3) + fregs[0x64] = val; + break; + case 0x69: + if (dev->type > 1) + fregs[0x69] = val & 0xfe; + else + fregs[0x69] = val & 0xfa; + break; + case 0x6a: + switch (dev->type) { + case 0: case 1: + default: + fregs[0x6a] = (fregs[0x6a] & 0xfb) | (val & 0x04); + if (dev->type > 0) { + fregs[0x0e] = (val & 0x04) ? 0x80 : 0x00; + dev->max_func = 0 + !!(val & 0x04); } - - piix_bus_master_handlers(dev, old_base); - } - break; - case 0x07: - dev->regs_ide[0x07] = val & 0x3e; - break; - case 0x0d: - dev->regs_ide[0x0d] = val; - break; - - case 0x20: - dev->regs_ide[0x20] = (val & ~0x0f) | 1; - if (valxor) - piix_bus_master_handlers(dev, old_base); - break; - case 0x21: - dev->regs_ide[0x21] = val; - if (valxor) - piix_bus_master_handlers(dev, old_base); - break; - - case 0x40: - dev->regs_ide[0x40] = val; - break; - case 0x41: - dev->regs_ide[0x41] = val; - if (valxor & 0x80) { - ide_pri_disable(); - if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) - ide_pri_enable(); - } - break; - case 0x42: - dev->regs_ide[0x42] = val; - break; - case 0x43: - dev->regs_ide[0x43] = val; - if (valxor & 0x80) { - ide_sec_disable(); - if ((val & 0x80) && (dev->regs_ide[0x04] & 0x01)) - ide_sec_enable(); - } - break; - case 0x44: - if (dev->type >= 3) dev->regs_ide[0x44] = val; - break; - } - } else { - piix_log("PIIX writing value %02X to register %02X\n", val, addr); - valxor = val ^ dev->regs[addr]; - - if ((addr >= 0x0f) && (addr < 0x4c)) + break; + case 3: + fregs[0x6a] = val & 0xd1; + dev->max_func = 1 + !!(val & 0x10); + break; + case 4: + fregs[0x6a] = val & 0x80; + break; + } + break; + case 0x6b: + if ((dev->type > 1) && (val & 0x80)) + fregs[0x6b] &= 0x7f; return; - - switch (addr) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: - return; - - case 0x4c: - if (valxor) { - if (dev->type == 3) - dma_alias_remove(); - else - dma_alias_remove_piix(); - if (!(val & 0x80)) - dma_alias_set(); - } + case 0x70: case 0x71: + if ((dev->type > 1) && (addr == 0x71)) break; - case 0x4e: - keyboard_at_set_mouse_scan((val & 0x10) ? 1 : 0); - break; - case 0x60: - piix_log("Set IRQ routing: INT A -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + if (dev->type < 4) { + piix_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val); + if (dev->type > 1) + fregs[addr] = val & 0xef; else - pci_set_irq_routing(PCI_INTA, val & 0xf); - break; - case 0x61: - piix_log("Set IRQ routing: INT B -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x62: - piix_log("Set IRQ routing: INT C -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x63: - piix_log("Set IRQ routing: INT D -> %02X\n", val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - case 0x6a: - if (dev->type == 3) - dev->regs[addr] = (val & 0xFD) | (dev->regs[addr] | 2); - else - dev->regs[addr] = (val & 0xFC) | (dev->regs[addr] | 3); - return; - case 0x70: - piix_log("Set MIRQ routing: MIRQ0 -> %02X\n", val); + fregs[addr] = val & 0xcf; if (val & 0x80) pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); else pci_set_mirq_routing(PCI_MIRQ0, val & 0xf); - break; - piix_log("MIRQ0 is %s\n", (val & 0x20) ? "disabled" : "enabled"); - case 0x71: - if (dev->type == 1) { - piix_log("Set MIRQ routing: MIRQ1 -> %02X\n", val); - if (val & 0x80) - pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); - else - pci_set_mirq_routing(PCI_MIRQ1, val & 0xf); - } - break; - } + piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled"); + } + break; + case 0x76: case 0x77: + if (dev->type > 1) + fregs[addr] = val & 0x87; + else + fregs[addr] = val & 0x8f; + break; + case 0x78: case 0x79: + if (dev->type < 4) + fregs[addr] = val; + break; + case 0x80: + if (dev->type > 1) + fregs[addr] = val & 0x7f; + break; + case 0x81: + if (dev->type > 1) + fregs[addr] = val & 0x0f; + break; + case 0x90: + if (dev->type > 3) + fregs[addr] = val; + break; + case 0x91: + if (dev->type > 3) + fregs[addr] = val & 0xfc; + break; + case 0x92: case 0x93: case 0x94: case 0x95: + if (dev->type == 4) { + if (addr & 0x01) + fregs[addr] = val & 0xc0; + else + fregs[addr] = val & 0xff; + ddma_update_io_mapping(dev, (addr >> 2) & 1); + } + break; + case 0xa0: + if (dev->type < 4) + fregs[addr] = val & 0x1f; + break; + case 0xa2: case 0xa5: case 0xa6: case 0xa8: + case 0xaa: case 0xac: case 0xae: + if (dev->type < 4) + fregs[addr] = val & 0xff; + break; + case 0xa3: case 0xab: + if (dev->type == 3) + fregs[addr] = val & 0x01; + break; + case 0xa4: + if (dev->type < 4) + fregs[addr] = val & 0xfb; + break; + case 0xa7: + if (dev->type == 3) + fregs[addr] = val & 0xef; + else if (dev->type < 3) + fregs[addr] = val; + break; + case 0xb0: + if (dev->type > 3) + fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73); + break; + case 0xb1: + if (dev->type > 3) + fregs[addr] = val & 0xdf; + break; + case 0xb2: + if (dev->type > 3) + fregs[addr] = val; + break; + case 0xb3: + if (dev->type > 3) + fregs[addr] = val & 0xfb; + break; + case 0xcb: + if (dev->type == 4) { + fregs[addr] = val & 0x3d; - dev->regs[addr] = val; + nvr_at_handler(0, 0x0070, dev->nvr); + nvr_at_handler(0, 0x0072, dev->nvr); + + if ((val & 0x01) && (dev->regs[2][0xff] & 0x10)) + nvr_at_handler(1, 0x0070, dev->nvr); + if (val & 0x04) + nvr_at_handler(1, 0x0072, dev->nvr); + + nvr_wp_set(!!(val & 0x08), 0, dev->nvr); + nvr_wp_set(!!(val & 0x10), 1, dev->nvr); + } + break; + } else if (func == 1) switch(addr) { /* IDE */ + case 0x04: + fregs[0x04] = (val & 5); + if (dev->type < 3) + fregs[0x04] |= 0x02; + piix_ide_legacy_handlers(dev, 0x03); + piix_ide_bm_handlers(dev); + break; + case 0x07: + if (val & 0x20) + fregs[0x07] &= 0xdf; + if (val & 0x10) + fregs[0x07] &= 0xef; + if (val & 0x08) + fregs[0x07] &= 0xf7; + break; + case 0x0d: + fregs[0x0d] = val & 0xf0; + break; + case 0x20: + fregs[0x20] = (val & 0xf0) | 1; + piix_ide_bm_handlers(dev); + break; + case 0x21: + fregs[0x21] = val; + piix_ide_bm_handlers(dev); + break; + case 0x40: case 0x42: + fregs[addr] = val; + break; + case 0x41: case 0x43: + fregs[addr] = val & ((dev->type > 1) ? 0xf3 : 0xb3); + piix_ide_legacy_handlers(dev, 1 << !!(addr & 0x02)); + break; + case 0x44: + if (dev->type > 1) + fregs[0x44] = val; + break; + case 0x48: + if (dev->type > 3) + fregs[0x48] = val & 0x0f; + break; + case 0x4a: case 0x4b: + if (dev->type > 4) + fregs[addr] = val & 0x33; + break; + } else if (func == 2) switch(addr) { /* USB */ + case 0x04: + fregs[0x04] = (val & 5); + usb_update_io_mapping(dev); + break; + case 0x07: + if (val & 0x20) + fregs[0x07] &= 0xdf; + if (val & 0x10) + fregs[0x07] &= 0xef; + if (val & 0x08) + fregs[0x07] &= 0xf7; + break; + case 0x0d: + fregs[0x0d] = val & 0xf0; + break; + case 0x20: + fregs[0x20] = (val & 0xe0) | 1; + usb_update_io_mapping(dev); + break; + case 0x21: + fregs[0x21] = val; + usb_update_io_mapping(dev); + break; + case 0x3c: + fregs[0x3c] = val; + break; + case 0x6a: + if (dev->type < 4) + fregs[0x6a] = val & 0x01; + break; + case 0xc0: + fregs[0xc0] = val; + break; + case 0xc1: + fregs[0xc1] = val & 0xbf; + break; + case 0xff: + if (dev->type >= 4) { + fregs[addr] = val & 0x10; + nvr_at_handler(0, 0x0070, dev->nvr); + if ((dev->regs[0][0xcb] & 0x01) && (dev->regs[2][0xff] & 0x10)) + nvr_at_handler(1, 0x0070, dev->nvr); + } + break; + } else if (func == 3) switch(addr) { /* Power Management */ + case 0x04: + fregs[0x04] = (val & 1); + power_update_io_mapping(dev); + smbus_update_io_mapping(dev); + break; + case 0x07: + if (val & 0x08) + fregs[0x07] &= 0xf7; + break; +#if 0 + case 0x3c: + fregs[0x3c] = val; + break; +#endif + case 0x40: + fregs[0x40] = (val & 0xc0) | 1; + power_update_io_mapping(dev); + break; + case 0x41: + fregs[0x41] = val; + power_update_io_mapping(dev); + break; + case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: + case 0x4c: case 0x4d: case 0x4e: + case 0x54: case 0x55: case 0x56: case 0x57: + case 0x59: case 0x5a: + case 0x5c: case 0x5d: case 0x5e: case 0x5f: + case 0x60: case 0x61: case 0x62: + case 0x64: case 0x65: + case 0x67: case 0x68: case 0x69: + case 0x6c: case 0x6e: case 0x6f: + case 0x70: case 0x71: + case 0x74: case 0x77: case 0x78: case 0x79: + case 0x7c: case 0x7d: + case 0xd3: case 0xd4: + case 0xd5: + fregs[addr] = val; + break; + case 0x4a: + fregs[addr] = val & 0x73; + break; + case 0x4b: + fregs[addr] = val & 0x01; + break; + case 0x4f: case 0x80: case 0xd2: + fregs[addr] = val & 0x0f; + if (addr == 0x80) + power_update_io_mapping(dev); + else if (addr == 0xd2) + smbus_update_io_mapping(dev); + break; + case 0x50: + fregs[addr] = val & 0x3f; + break; + case 0x51: + fregs[addr] = val & 0x58; + break; + case 0x52: + fregs[addr] = val & 0x7f; + break; + case 0x58: + fregs[addr] = val & 0x77; + break; + case 0x5b: + fregs[addr] = val & 0x03; + break; + case 0x63: + fregs[addr] = val & 0xf7; + break; + case 0x66: + fregs[addr] = val & 0xef; + break; + case 0x6a: case 0x72: case 0x7a: case 0x7e: + fregs[addr] = val & 0x1f; + break; + case 0x6d: case 0x75: + fregs[addr] = val & 0x80; + break; + case 0x90: + fregs[0x90] = (val & 0xf0) | 1; + smbus_update_io_mapping(dev); + break; + case 0x91: + fregs[0x91] = val; + smbus_update_io_mapping(dev); + break; } } @@ -256,133 +877,17 @@ static uint8_t piix_read(int func, int addr, void *priv) { piix_t *dev = (piix_t *) priv; + uint8_t ret = 0xff, *fregs; - if ((func == 1) && (dev->type & 0x100)) /* PB640's PIIX has no IDE part. */ - return 0xff; - if (func > 1) - return 0xff; + /* Return on unsupported function. */ + if (func <= dev->max_func) { + fregs = (uint8_t *) dev->regs[func]; + ret = fregs[addr]; - if (func == 1) { /*IDE*/ - if (addr == 4) - return (dev->regs_ide[addr] & 5) | 2; - else if (addr == 5) - return 0; - else if (addr == 6) - return 0x80; - else if (addr == 7) - return dev->regs_ide[addr] & 0x3E; - else if (addr == 0xD) - return dev->regs_ide[addr] & 0xF0; - else if (addr == 0x20) - return (dev->regs_ide[addr] & 0xF0) | 1; - else if (addr == 0x22) - return 0; - else if (addr == 0x23) - return 0; - else if (addr == 0x41) { - if (dev->type == 3) - return dev->regs_ide[addr] & 0xF3; - else - return dev->regs_ide[addr] & 0xB3; - } else if (addr == 0x43) { - if (dev->type == 3) - return dev->regs_ide[addr] & 0xF3; - else - return dev->regs_ide[addr] & 0xB3; - } else - return dev->regs_ide[addr]; - } else { - if ((addr & 0xFC) == 0x60) - return dev->regs[addr] & 0x8F; - - if (addr == 4) { - if (dev->type & 0x100) - return (dev->regs[addr] & 0x80) | 0x0F; - else - return (dev->regs[addr] & 0x80) | 7; - } else if (addr == 5) { - if (dev->type == 3) - return dev->regs[addr] & 1; - else - return 0; - } else if (addr == 6) - return dev->regs[addr] & 0x80; - else if (addr == 7) { - if (dev->type == 3) - return dev->regs[addr]; - else { - if (dev->type & 0x100) - return dev->regs[addr] & 0x02; - else - return dev->regs[addr] & 0x3E; - } - } else if (addr == 0x4E) - return (dev->regs[addr] & 0xEF) | keyboard_at_get_mouse_scan(); - else if (addr == 0x69) - return dev->regs[addr] & 0xFE; - else if (addr == 0x6A) { - if (dev->type == 3) - return dev->regs[addr] & 0xD1; - else - return dev->regs[addr] & 0x07; - } else if (addr == 0x6B) { - if (dev->type == 3) - return dev->regs[addr] & 0x80; - else - return 0; - } - else if (addr == 0x70) { - if (dev->type == 3) - return dev->regs[addr] & 0xEF; - else - return dev->regs[addr] & 0xCF; - } else if (addr == 0x71) { - if (dev->type == 3) - return 0; - else - return dev->regs[addr] & 0xCF; - } else if (addr == 0x76) { - if (dev->type == 3) - return dev->regs[addr] & 0x87; - else - return dev->regs[addr] & 0x8F; - } else if (addr == 0x77) { - if (dev->type == 3) - return dev->regs[addr] & 0x87; - else - return dev->regs[addr] & 0x8F; - } else if (addr == 0x80) { - if (dev->type == 3) - return dev->regs[addr] & 0x7F; - else if (dev->type == 1) - return 0; - } else if (addr == 0x82) { - if (dev->type == 3) - return dev->regs[addr] & 0x0F; - else - return 0; - } else if (addr == 0xA0) - return dev->regs[addr] & 0x1F; - else if (addr == 0xA3) { - if (dev->type == 3) - return dev->regs[addr] & 1; - else - return 0; - } else if (addr == 0xA7) { - if (dev->type == 3) - return dev->regs[addr]; - else - return dev->regs[addr] & 0xEF; - } else if (addr == 0xAB) { - if (dev->type == 3) - return dev->regs[addr]; - else - return dev->regs[addr] & 0xFE; - } else - return dev->regs[addr]; + // pclog("PIIX function %i read: %02X from %02X\n", func, ret, addr); } - return 0; + return ret; } @@ -391,7 +896,11 @@ board_write(uint16_t port, uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; - if (port == 0x00e0) + if (port == 0x0078) + dev->board_config[0] = val; + else if (port == 0x0079) + dev->board_config[1] = val; + else if (port == 0x00e0) dev->cur_readout_reg = val; else if (port == 0x00e1) dev->readout_regs[dev->cur_readout_reg] = val; @@ -402,9 +911,13 @@ static uint8_t board_read(uint16_t port, void *priv) { piix_t *dev = (piix_t *) priv; - uint8_t ret = 0xff; + uint8_t ret = 0x64; - if (port == 0x00e0) + if (port == 0x0078) + ret = dev->board_config[0]; + else if (port == 0x0079) + ret = dev->board_config[1]; + else if (port == 0x00e0) ret = dev->cur_readout_reg; else if (port == 0x00e1) ret = dev->readout_regs[dev->cur_readout_reg]; @@ -414,89 +927,127 @@ board_read(uint16_t port, void *priv) static void -piix_reset_hard(void *priv) +piix_reset_hard(piix_t *dev) { - piix_t *piix = (piix_t *) priv; + int i; + uint8_t *fregs; - uint16_t old_base = (piix->regs_ide[0x20] & 0xf0) | (piix->regs_ide[0x21] << 8); + uint16_t old_base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8); - if (!(piix->type & 0x100)) { /* PB640's PIIX has no IDE part. */ - sff_bus_master_reset(piix->bm[0], old_base); - sff_bus_master_reset(piix->bm[1], old_base + 8); + /* Type 0 is the PB640's PIIX without IDE. */ + if (dev->type > 0) { + sff_bus_master_reset(dev->bm[0], old_base); + sff_bus_master_reset(dev->bm[1], old_base + 8); + + if (dev->type == 4) { + sff_set_irq_mode(dev->bm[0], 0); + sff_set_irq_mode(dev->bm[1], 0); + } + + // pclog("piix_reset_hard()\n"); + ide_pri_disable(); + ide_sec_disable(); } - memset(piix->regs, 0, 256); - memset(piix->regs_ide, 0, 256); + if (dev->type > 3) { + nvr_at_handler(0, 0x0072, dev->nvr); + nvr_wp_set(0, 0, dev->nvr); + nvr_wp_set(0, 1, dev->nvr); + } else + nvr_at_handler(1, 0x0072, dev->nvr); + nvr_at_handler(1, 0x0074, dev->nvr); + nvr_at_handler(1, 0x0076, dev->nvr); - piix->regs[0x00] = 0x86; piix->regs[0x01] = 0x80; /*Intel*/ - if (piix->type == 3) { - piix->regs[0x02] = 0x00; piix->regs[0x03] = 0x70; /*82371SB (PIIX3)*/ - } else { - piix->regs[0x02] = 0x2e; piix->regs[0x03] = 0x12; /*82371FB (PIIX)*/ + /* Clear all 4 functions' arrays and set their vendor and device ID's. */ + for (i = 0; i < 4; i++) { + memset(dev->regs[i], 0, 256); + dev->regs[i][0x00] = 0x86; dev->regs[i][0x01] = 0x80; /* Intel */ + dev->regs[i][0x02] = (dev->func0_id & 0xff) + (i << dev->func_shift); + dev->regs[i][0x03] = (dev->func0_id >> 8); } - if (piix->type & 0x100) - piix->regs[0x04] = 0x06; - else - piix->regs[0x04] = 0x07; - piix->regs[0x05] = 0x00; - piix->regs[0x06] = 0x80; piix->regs[0x07] = 0x02; - if (piix->type & 0x100) - piix->regs[0x08] = 0x02; /*A0 stepping*/ - else - piix->regs[0x08] = 0x00; /*A0 stepping*/ - piix->regs[0x09] = 0x00; piix->regs[0x0a] = 0x01; piix->regs[0x0b] = 0x06; - if (piix->type & 0x100) - piix->regs[0x0e] = 0x00; /*Single-function device*/ - else - piix->regs[0x0e] = 0x80; /*Multi-function device*/ - piix->regs[0x4c] = 0x4d; - piix->regs[0x4e] = 0x03; - if (piix->type == 3) - piix->regs[0x4f] = 0x00; - piix->regs[0x60] = piix->regs[0x61] = piix->regs[0x62] = piix->regs[0x63] = 0x80; - piix->regs[0x69] = 0x02; - piix->regs[0x70] = 0xc0; - if (piix->type != 3) - piix->regs[0x71] = 0xc0; - piix->regs[0x76] = piix->regs[0x77] = 0x0c; - piix->regs[0x78] = 0x02; piix->regs[0x79] = 0x00; - if (piix->type == 3) { - piix->regs[0x80] = piix->regs[0x82] = 0x00; - } - piix->regs[0xa0] = 0x08; - piix->regs[0xa2] = piix->regs[0xa3] = 0x00; - piix->regs[0xa4] = piix->regs[0xa5] = piix->regs[0xa6] = piix->regs[0xa7] = 0x00; - piix->regs[0xa8] = 0x0f; - piix->regs[0xaa] = piix->regs[0xab] = 0x00; - piix->regs[0xac] = 0x00; - piix->regs[0xae] = 0x00; - piix->regs_ide[0x00] = 0x86; piix->regs_ide[0x01] = 0x80; /*Intel*/ - if (piix->type == 3) { - piix->regs_ide[0x02] = 0x10; piix->regs_ide[0x03] = 0x70; /*82371SB (PIIX3)*/ - } else { - piix->regs_ide[0x02] = 0x30; piix->regs_ide[0x03] = 0x12; /*82371FB (PIIX)*/ + /* Function 0: PCI to ISA Bridge */ + fregs = (uint8_t *) dev->regs[0]; + // pclog("PIIX Function 0: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x04] = (dev->type > 0) ? 0x07 : 0x06; /* Check the value for the PB640 PIIX. */ + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + fregs[0x08] = (dev->type > 0) ? 0x00 : 0x02; /* Should normal PIIX alos return 0x02? */ + fregs[0x09] = 0x00; + fregs[0x0a] = 0x01; fregs[0x0b] = 0x06; + fregs[0x0e] = (dev->type > 0) ? 0x80 : 0x00; + fregs[0x4c] = 0x4d; + fregs[0x4e] = 0x03; + fregs[0x60] = fregs[0x61] = fregs[0x62] = fregs[0x63] = 0x80; + fregs[0x64] = (dev->type > 3) ? 0x10 : 0x00; + fregs[0x69] = 0x02; + fregs[0x70] = (dev->type < 4) ? 0x80 : 0x00; + fregs[0x71] = (dev->type < 3) ? 0x80 : 0x00; + fregs[0x76] = fregs[0x77] = (dev->type > 1) ? 0x04 : 0x0c; + fregs[0x78] = (dev->type < 4) ? 0x02 : 0x00; + fregs[0xa0] = (dev->type < 4) ? 0x08 : 0x00; + fregs[0xa8] = (dev->type < 4) ? 0x0f : 0x00; + if (dev->type == 4) + fregs[0xb0] = (is_pentium) ? 0x00 : 0x04; + fregs[0xcb] = (dev->type > 3) ? 0x21 : 0x00; + dev->max_func = 0; + + /* Function 1: IDE */ + if (dev->type > 0) { + fregs = (uint8_t *) dev->regs[1]; + // pclog("PIIX Function 1: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x04] = (dev->type > 3) ? 0x05 : 0x07; + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + fregs[0x09] = 0x80; + fregs[0x0a] = 0x01; fregs[0x0b] = 0x01; + fregs[0x20] = 0x01; + dev->max_func = 1; + } + + /* Function 2: USB */ + if (dev->type > 2) { + fregs = (uint8_t *) dev->regs[2]; + // pclog("PIIX Function 2: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x04] = 0x05; + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + fregs[0x0a] = 0x03; fregs[0x0b] = 0x0c; + fregs[0x20] = 0x01; + fregs[0x3d] = 0x04; + fregs[0x60] = (dev->type > 3) ? 0x10: 0x00; + fregs[0x6a] = (dev->type == 3) ? 0x01 : 0x00; + fregs[0xc1] = 0x20; + fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00; + dev->max_func = 2; + } + + /* Function 3: Power Management */ + if (dev->type > 3) { + fregs = (uint8_t *) dev->regs[3]; + // pclog("PIIX Function 3: 8086:%02X%02X\n", fregs[0x03], fregs[0x02]); + fregs[0x06] = 0x80; fregs[0x07] = 0x02; + fregs[0x0a] = 0x80; fregs[0x0b] = 0x06; + /* NOTE: The Specification Update says this should default to 0x00 and be read-only. */ + // fregs[0x3d] = 0x01; + fregs[0x40] = 0x01; + fregs[0x90] = 0x01; + dev->max_func = 3; } - piix->regs_ide[0x04] = 0x03; piix->regs_ide[0x05] = 0x00; - piix->regs_ide[0x06] = 0x80; piix->regs_ide[0x07] = 0x02; - piix->regs_ide[0x08] = 0x00; - piix->regs_ide[0x09] = 0x80; piix->regs_ide[0x0a] = 0x01; piix->regs_ide[0x0b] = 0x01; - piix->regs_ide[0x0d] = 0x00; - piix->regs_ide[0x0e] = 0x00; - piix->regs_ide[0x20] = 0x01; piix->regs_ide[0x21] = piix->regs_ide[0x22] = piix->regs_ide[0x23] = 0x00; /*Bus master interface base address*/ - piix->regs_ide[0x40] = piix->regs_ide[0x42] = 0x00; - piix->regs_ide[0x41] = piix->regs_ide[0x43] = 0x00; - if (piix->type == 3) - piix->regs_ide[0x44] = 0x00; pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); - if (piix->type != 3) + if (dev->type < 4) + pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED); + if (dev->type < 3) pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED); + + if (dev->type == 4) { + dev->power.gporeg[0] = 0xff; + dev->power.gporeg[1] = 0xbf; + dev->power.gporeg[2] = 0xff; + dev->power.gporeg[3] = 0x7f; + } } @@ -512,30 +1063,37 @@ piix_close(void *p) static void *piix_init(const device_t *info) { - piix_t *piix = (piix_t *) malloc(sizeof(piix_t)); - memset(piix, 0, sizeof(piix_t)); + piix_t *dev = (piix_t *) malloc(sizeof(piix_t)); + memset(dev, 0, sizeof(piix_t)); - pci_add_card(7, piix_read, piix_write, piix); + dev->type = info->local & 0xff; + dev->func_shift = info->local >> 8; + dev->func0_id = info->local >> 16; - piix->type = info->local; + dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev); + // pclog("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); - device_add(&apm_device); - - if (!(piix->type & 0x100)) { /* PB640's PIIX has no IDE part. */ - piix->bm[0] = device_add_inst(&sff8038i_device, 1); - piix->bm[1] = device_add_inst(&sff8038i_device, 2); + if (dev->type > 0) { /* PB640's PIIX has no IDE part. */ + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); } - piix_reset_hard(piix); + if (dev->type >= 3) + dev->nvr = device_add(&piix4_nvr_device); + piix_reset_hard(dev); + + device_add(&apm_device); device_add(&port_92_pci_device); dma_alias_set(); - pci_enable_mirq(0); - pci_enable_mirq(1); + if (dev->type < 4) + pci_enable_mirq(0); + if (dev->type < 3) + pci_enable_mirq(1); - piix->readout_regs[1] = 0x40; + dev->readout_regs[1] = 0x40; /* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined): @@ -547,73 +1105,84 @@ static void 1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz; 1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */ - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].pci_speed) { - case 20000000: - piix->readout_regs[1] |= 0x30; - break; - case 25000000: - default: - piix->readout_regs[1] |= 0x00; - break; - case 30000000: - piix->readout_regs[1] |= 0x20; - break; - case 33333333: - piix->readout_regs[1] |= 0x10; - break; - } + if (cpu_busspeed <= 0x40000000) + dev->readout_regs[1] |= 0x30; + else if ((cpu_busspeed > 0x40000000) && (cpu_busspeed <= 0x50000000)) + dev->readout_regs[1] |= 0x00; + else if ((cpu_busspeed > 0x50000000) && (cpu_busspeed <= 0x60000000)) + dev->readout_regs[1] |= 0x20; + else if (cpu_busspeed > 0x60000000) + dev->readout_regs[1] |= 0x10; +#if 0 switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) { case 75000000: - piix->readout_regs[1] |= 0x82; /* 50 MHz * 1.5 multiplier */ + dev->readout_regs[1] |= 0x82; /* 50 MHz * 1.5 multiplier */ break; case 90000000: - piix->readout_regs[1] |= 0x82; /* 60 MHz * 1.5 multiplier */ + dev->readout_regs[1] |= 0x82; /* 60 MHz * 1.5 multiplier */ break; case 100000000: - if ((piix->readout_regs[1] & 0x30) == 0x10) - piix->readout_regs[1] |= 0x82; /* 66 MHz * 1.5 multiplier */ + if ((dev->readout_regs[1] & 0x30) == 0x10) + dev->readout_regs[1] |= 0x82; /* 66 MHz * 1.5 multiplier */ else - piix->readout_regs[1] |= 0x02; /* 50 MHz * 2.0 multiplier */ + dev->readout_regs[1] |= 0x02; /* 50 MHz * 2.0 multiplier */ break; case 12000000: - piix->readout_regs[1] |= 0x02; /* 60 MHz * 2.0 multiplier */ + dev->readout_regs[1] |= 0x02; /* 60 MHz * 2.0 multiplier */ break; case 125000000: - piix->readout_regs[1] |= 0x00; /* 50 MHz * 2.5 multiplier */ + dev->readout_regs[1] |= 0x00; /* 50 MHz * 2.5 multiplier */ break; case 133333333: - piix->readout_regs[1] |= 0x02; /* 66 MHz * 2.0 multiplier */ + dev->readout_regs[1] |= 0x02; /* 66 MHz * 2.0 multiplier */ break; case 150000000: - if ((piix->readout_regs[1] & 0x30) == 0x20) - piix->readout_regs[1] |= 0x00; /* 60 MHz * 2.5 multiplier */ + if ((dev->readout_regs[1] & 0x30) == 0x20) + dev->readout_regs[1] |= 0x00; /* 60 MHz * 2.5 multiplier */ else - piix->readout_regs[1] |= 0x80; /* 50 MHz * 3.0 multiplier */ + dev->readout_regs[1] |= 0x80; /* 50 MHz * 3.0 multiplier */ break; case 166666666: - piix->readout_regs[1] |= 0x00; /* 66 MHz * 2.5 multiplier */ + dev->readout_regs[1] |= 0x00; /* 66 MHz * 2.5 multiplier */ break; case 180000000: - piix->readout_regs[1] |= 0x80; /* 60 MHz * 3.0 multiplier */ + dev->readout_regs[1] |= 0x80; /* 60 MHz * 3.0 multiplier */ break; case 200000000: - piix->readout_regs[1] |= 0x80; /* 66 MHz * 3.0 multiplier */ + dev->readout_regs[1] |= 0x80; /* 66 MHz * 3.0 multiplier */ break; } +#else + if (cpu_dmulti <= 1.5) + dev->readout_regs[1] |= 0x82; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + dev->readout_regs[1] |= 0x02; + else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) + dev->readout_regs[1] |= 0x00; + else if (cpu_dmulti > 2.5) + dev->readout_regs[1] |= 0x80; +#endif - io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, piix); - io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, piix); + io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); + io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); - return piix; + dev->board_config[0] = 0xff; + /* Register 0x0079: */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + dev->board_config[1] = 0x64; + + return dev; } -const device_t piix_device = +const device_t piix_pb640_device = { - "Intel 82371FB (PIIX)", + "Intel 82371FB (PIIX) (PB640)", DEVICE_PCI, - 1, + 0x122e0100, piix_init, piix_close, NULL, @@ -623,11 +1192,11 @@ const device_t piix_device = NULL }; -const device_t piix_pb640_device = +const device_t piix_device = { - "Intel 82371FB (PIIX) (PB640)", + "Intel 82371FB (PIIX)", DEVICE_PCI, - 0x101, + 0x122e0101, piix_init, piix_close, NULL, @@ -641,7 +1210,21 @@ const device_t piix3_device = { "Intel 82371SB (PIIX3)", DEVICE_PCI, - 3, + 0x70000403, + piix_init, + piix_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +const device_t piix4_device = +{ + "Intel 82371AB/EB (PIIX4/PIIX4E)", + DEVICE_PCI, + 0x71100004, piix_init, piix_close, NULL, diff --git a/src/intel_piix.d b/src/intel_piix.d new file mode 100644 index 000000000..d01682751 --- /dev/null +++ b/src/intel_piix.d @@ -0,0 +1,5 @@ +intel_piix.o: intel_piix.c 86box.h cdrom/cdrom.h cpu_common/cpu.h \ + scsi/scsi_device.h scsi/scsi_cdrom.h dma.h 86box_io.h device.h apm.h \ + keyboard.h mem.h timer.h nvr.h pci.h pic.h port_92.h disk/hdc.h \ + disk/hdc_ide.h disk/hdc_ide_sff8038i.h disk/zip.h machine/machine.h \ + piix.h diff --git a/src/intel_sio.c b/src/intel_sio.c index 45cdf2975..d0a5da9f4 100644 --- a/src/intel_sio.c +++ b/src/intel_sio.c @@ -21,7 +21,7 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "apm.h" #include "dma.h" #include "mem.h" @@ -29,7 +29,7 @@ #include "timer.h" #include "pit.h" #include "port_92.h" -#include "machine/machine.h" +#include "machine.h" #include "intel_sio.h" @@ -248,7 +248,7 @@ sio_config_read(uint16_t port, void *priv) case 5: ret = 0xd3; - switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].pci_speed) { + switch (cpu_pci_speed) { case 20000000: ret |= 0x0c; break; @@ -341,7 +341,7 @@ sio_init(const device_t *info) sio_t *sio = (sio_t *) malloc(sizeof(sio_t)); memset(sio, 0, sizeof(sio_t)); - pci_add_card(2, sio_read, sio_write, sio); + pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, sio); device_add(&apm_device); diff --git a/src/intel_sio.d b/src/intel_sio.d new file mode 100644 index 000000000..d84f96f6f --- /dev/null +++ b/src/intel_sio.d @@ -0,0 +1,3 @@ +intel_sio.o: intel_sio.c 86box.h device.h 86box_io.h apm.h dma.h mem.h \ + pci.h timer.h cpu_common/cpu.h pit.h port_92.h machine/machine.h \ + intel_sio.h diff --git a/src/io.c b/src/io.c index 8e1ed59f8..23debad58 100644 --- a/src/io.c +++ b/src/io.c @@ -25,9 +25,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "io.h" -#include "cpu/cpu.h" -#include "machine/m_amstrad.h" +#include "86box_io.h" +#include "cpu.h" +#include "m_amstrad.h" #define NPORTS 65536 /* PC/AT supports 64K ports */ @@ -333,9 +333,27 @@ inb(uint16_t port) io_log("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, ret); #endif + /* if (port == 0x386) { + ret = 0x00; + found = 1; + } + + if (port == 0x406) { + ret = 0x00; + found = 1; + } + + if (port == 0xf87) { + ret = 0x00; + found = 1; + } */ + if (!found) sub_cycles(io_delay); + if (!found) + pclog("inb(%04X) = %02X\n", port, ret); + return(ret); } @@ -365,6 +383,9 @@ outb(uint16_t port, uint8_t val) if (!found) sub_cycles(io_delay); + if (!found) + pclog("outb(%04X, %02X)\n", port, val); + return; } diff --git a/src/io.d b/src/io.d new file mode 100644 index 000000000..f5fcc0a5e --- /dev/null +++ b/src/io.d @@ -0,0 +1 @@ +io.o: io.c 86box.h 86box_io.h cpu_common/cpu.h machine/m_amstrad.h diff --git a/src/ip_icmp.d b/src/ip_icmp.d new file mode 100644 index 000000000..a04ef0826 --- /dev/null +++ b/src/ip_icmp.d @@ -0,0 +1,9 @@ +ip_icmp.o: network/slirp/ip_icmp.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h network/slirp/ip_icmp.h diff --git a/src/ip_input.d b/src/ip_input.d new file mode 100644 index 000000000..757074d32 --- /dev/null +++ b/src/ip_input.d @@ -0,0 +1,9 @@ +ip_input.o: network/slirp/ip_input.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h network/slirp/ip_icmp.h diff --git a/src/ip_output.d b/src/ip_output.d new file mode 100644 index 000000000..61b9a05b7 --- /dev/null +++ b/src/ip_output.d @@ -0,0 +1,9 @@ +ip_output.o: network/slirp/ip_output.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/isamem.c b/src/isamem.c index a6f29deb5..9a37909c2 100644 --- a/src/isamem.c +++ b/src/isamem.c @@ -74,8 +74,8 @@ #include #include #include "86box.h" -#include "machine/machine.h" -#include "io.h" +#include "machine.h" +#include "86box_io.h" #include "mem.h" #include "device.h" #include "ui.h" diff --git a/src/isamem.d b/src/isamem.d new file mode 100644 index 000000000..77a9482a2 --- /dev/null +++ b/src/isamem.d @@ -0,0 +1,2 @@ +isamem.o: isamem.c 86box.h machine/machine.h 86box_io.h mem.h device.h \ + ui.h plat.h lang/language.h isamem.h diff --git a/src/isartc.c b/src/isartc.c index 22da01027..c83460aaa 100644 --- a/src/isartc.c +++ b/src/isartc.c @@ -71,10 +71,10 @@ #include #include #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "timer.h" -#include "machine/machine.h" -#include "io.h" +#include "machine.h" +#include "86box_io.h" #include "device.h" #include "nvr.h" #include "ui.h" diff --git a/src/isartc.d b/src/isartc.d new file mode 100644 index 000000000..39c456dd2 --- /dev/null +++ b/src/isartc.d @@ -0,0 +1,2 @@ +isartc.o: isartc.c 86box.h cpu_common/cpu.h timer.h machine/machine.h \ + 86box_io.h device.h nvr.h ui.h plat.h lang/language.h pic.h isartc.h diff --git a/src/joystick_ch_flightstick_pro.d b/src/joystick_ch_flightstick_pro.d new file mode 100644 index 000000000..186aa0302 --- /dev/null +++ b/src/joystick_ch_flightstick_pro.d @@ -0,0 +1,3 @@ +joystick_ch_flightstick_pro.o: game/joystick_ch_flightstick_pro.c 86box.h \ + device.h timer.h cpu_common/cpu.h game/gameport.h \ + game/joystick_standard.h diff --git a/src/joystick_standard.d b/src/joystick_standard.d new file mode 100644 index 000000000..c2dd05d60 --- /dev/null +++ b/src/joystick_standard.d @@ -0,0 +1,2 @@ +joystick_standard.o: game/joystick_standard.c 86box.h device.h timer.h \ + cpu_common/cpu.h game/gameport.h game/joystick_standard.h diff --git a/src/joystick_sw_pad.d b/src/joystick_sw_pad.d new file mode 100644 index 000000000..047f86f12 --- /dev/null +++ b/src/joystick_sw_pad.d @@ -0,0 +1,2 @@ +joystick_sw_pad.o: game/joystick_sw_pad.c 86box.h device.h timer.h \ + cpu_common/cpu.h game/gameport.h game/joystick_sw_pad.h diff --git a/src/joystick_tm_fcs.d b/src/joystick_tm_fcs.d new file mode 100644 index 000000000..4124b3d85 --- /dev/null +++ b/src/joystick_tm_fcs.d @@ -0,0 +1,2 @@ +joystick_tm_fcs.o: game/joystick_tm_fcs.c 86box.h device.h timer.h \ + cpu_common/cpu.h game/gameport.h game/joystick_standard.h diff --git a/src/keyboard.c b/src/keyboard.c index 68f5017df..1c770f69d 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -23,7 +23,7 @@ #include #include #include "86box.h" -#include "machine/machine.h" +#include "machine.h" #include "keyboard.h" diff --git a/src/keyboard.d b/src/keyboard.d new file mode 100644 index 000000000..19f96cb7f --- /dev/null +++ b/src/keyboard.d @@ -0,0 +1 @@ +keyboard.o: keyboard.c 86box.h machine/machine.h keyboard.h diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 7da1c4380..a3c12dcd4 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -26,22 +26,22 @@ #define HAVE_STDARG_H #include #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "timer.h" -#include "io.h" +#include "86box_io.h" #include "pic.h" #include "pit.h" #include "ppi.h" #include "mem.h" #include "device.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" -#include "machine/m_at_t3100e.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" +#include "machine.h" +#include "m_xt_xi8088.h" +#include "m_at_t3100e.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" #include "keyboard.h" @@ -1002,6 +1002,7 @@ write_output(atkbd_t *dev, uint8_t val) cpu_set_edx(); } } + /* Mask off the A20 stuff because we use mem_a20_key directly for that. */ dev->output_port = val; } @@ -2270,7 +2271,7 @@ kbd_reset(void *priv) dev->first_write = 1; dev->status = STAT_UNLOCKED | STAT_CD; dev->mem[0] = 0x01; - if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) + // if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_XI8088) dev->mem[0] |= CCB_TRANSLATE; dev->wantirq = 0; write_output(dev, 0xcf); diff --git a/src/keyboard_at.d b/src/keyboard_at.d new file mode 100644 index 000000000..d509d7878 --- /dev/null +++ b/src/keyboard_at.d @@ -0,0 +1,4 @@ +keyboard_at.o: keyboard_at.c 86box.h cpu_common/cpu.h timer.h 86box_io.h \ + pic.h pit.h ppi.h mem.h device.h machine/machine.h machine/m_xt_xi8088.h \ + machine/../device.h machine/m_at_t3100e.h floppy/fdd.h floppy/fdc.h \ + sound/sound.h sound/snd_speaker.h video/video.h keyboard.h diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 7f8be716c..e74e926fb 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -26,18 +26,18 @@ #include "86box.h" #include "device.h" #include "timer.h" -#include "floppy/fdd.h" -#include "machine/machine.h" -#include "machine/m_xt_t1000.h" -#include "io.h" +#include "fdd.h" +#include "machine.h" +#include "m_xt_t1000.h" +#include "86box_io.h" #include "pic.h" #include "pit.h" #include "ppi.h" #include "mem.h" #include "rom.h" -#include "sound/sound.h" -#include "sound/snd_speaker.h" -#include "video/video.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" #include "keyboard.h" diff --git a/src/keyboard_xt.d b/src/keyboard_xt.d new file mode 100644 index 000000000..b80b09eba --- /dev/null +++ b/src/keyboard_xt.d @@ -0,0 +1,4 @@ +keyboard_xt.o: keyboard_xt.c 86box.h device.h timer.h cpu_common/cpu.h \ + floppy/fdd.h machine/machine.h machine/m_xt_t1000.h 86box_io.h pic.h \ + pit.h ppi.h mem.h rom.h sound/sound.h sound/snd_speaker.h video/video.h \ + keyboard.h diff --git a/src/lpt.c b/src/lpt.c index f67eba3cc..646cc2cd1 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -6,12 +6,11 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "lpt.h" #include "pic.h" -#include "sound/snd_lpt_dac.h" -#include "sound/snd_lpt_dss.h" -#include "printer/prt_devs.h" +#include "sound.h" +#include "prt_devs.h" lpt_port_t lpt_ports[3]; diff --git a/src/lpt.d b/src/lpt.d new file mode 100644 index 000000000..3032239c7 --- /dev/null +++ b/src/lpt.d @@ -0,0 +1,2 @@ +lpt.o: lpt.c 86box.h 86box_io.h lpt.h pic.h sound/sound.h \ + printer/prt_devs.h diff --git a/src/lpt.h b/src/lpt.h index c6a95fc4e..43a91a09a 100644 --- a/src/lpt.h +++ b/src/lpt.h @@ -53,3 +53,8 @@ extern char * lpt_device_get_name(int id); extern char * lpt_device_get_internal_name(int id); extern int lpt_device_get_from_internal_name(char *s); + +extern const lpt_device_t lpt_dac_device; +extern const lpt_device_t lpt_dac_stereo_device; + +extern const lpt_device_t dss_device; diff --git a/src/m_amstrad.d b/src/m_amstrad.d new file mode 100644 index 000000000..e533d5b29 --- /dev/null +++ b/src/m_amstrad.d @@ -0,0 +1,5 @@ +m_amstrad.o: machine/m_amstrad.c 86box.h cpu_common/cpu.h timer.h \ + 86box_io.h nmi.h pic.h pit.h ppi.h mem.h rom.h device.h nvr.h keyboard.h \ + mouse.h game/gameport.h lpt.h floppy/fdd.h floppy/fdc.h sound/sound.h \ + sound/snd_speaker.h video/video.h video/vid_cga.h video/vid_ega.h \ + video/vid_mda.h machine/machine.h machine/m_amstrad.h diff --git a/src/m_at.d b/src/m_at.d new file mode 100644 index 000000000..838e79240 --- /dev/null +++ b/src/m_at.d @@ -0,0 +1,3 @@ +m_at.o: machine/m_at.c 86box.h timer.h cpu_common/cpu.h pic.h pit.h dma.h \ + mem.h device.h floppy/fdd.h floppy/fdc.h nvr.h game/gameport.h \ + keyboard.h lpt.h rom.h disk/hdc.h machine/machine.h diff --git a/src/m_at_286_386sx.d b/src/m_at_286_386sx.d new file mode 100644 index 000000000..07256e985 --- /dev/null +++ b/src/m_at_286_386sx.d @@ -0,0 +1,3 @@ +m_at_286_386sx.o: machine/m_at_286_386sx.c 86box.h cpu_common/cpu.h \ + timer.h 86box_io.h device.h chipset/chipset.h keyboard.h mem.h rom.h \ + floppy/fdd.h floppy/fdc.h disk/hdc.h video/video.h machine/machine.h diff --git a/src/m_at_386dx_486.d b/src/m_at_386dx_486.d new file mode 100644 index 000000000..8a9ebc5ad --- /dev/null +++ b/src/m_at_386dx_486.d @@ -0,0 +1,4 @@ +m_at_386dx_486.o: machine/m_at_386dx_486.c 86box.h cpu_common/cpu.h \ + timer.h 86box_io.h device.h chipset/chipset.h keyboard.h mem.h nvr.h \ + pci.h floppy/fdd.h floppy/fdc.h rom.h sio.h disk/hdc.h video/video.h \ + intel_flash.h intel_sio.h machine/machine.h diff --git a/src/m_at_commodore.d b/src/m_at_commodore.d new file mode 100644 index 000000000..2c81c8982 --- /dev/null +++ b/src/m_at_commodore.d @@ -0,0 +1,3 @@ +m_at_commodore.o: machine/m_at_commodore.c 86box.h device.h timer.h \ + cpu_common/cpu.h 86box_io.h mem.h lpt.h rom.h serial.h floppy/fdd.h \ + floppy/fdc.h machine/machine.h diff --git a/src/m_at_compaq.d b/src/m_at_compaq.d new file mode 100644 index 000000000..a5729c23c --- /dev/null +++ b/src/m_at_compaq.d @@ -0,0 +1,3 @@ +m_at_compaq.o: machine/m_at_compaq.c 86box.h cpu_common/cpu.h timer.h \ + mem.h rom.h device.h floppy/fdd.h floppy/fdc.h disk/hdc.h disk/hdc_ide.h \ + machine/machine.h diff --git a/src/m_at_socket4_5.d b/src/m_at_socket4_5.d new file mode 100644 index 000000000..3bc15f1a7 --- /dev/null +++ b/src/m_at_socket4_5.d @@ -0,0 +1,4 @@ +m_at_socket4_5.o: machine/m_at_socket4_5.c 86box.h mem.h 86box_io.h rom.h \ + pci.h device.h chipset/chipset.h disk/hdc.h disk/hdc_ide.h timer.h \ + cpu_common/cpu.h floppy/fdd.h floppy/fdc.h keyboard.h intel_flash.h \ + intel_sio.h piix.h sio.h video/video.h machine/machine.h diff --git a/src/m_at_socket7_s7.d b/src/m_at_socket7_s7.d new file mode 100644 index 000000000..cd540c489 --- /dev/null +++ b/src/m_at_socket7_s7.d @@ -0,0 +1,4 @@ +m_at_socket7_s7.o: machine/m_at_socket7_s7.c 86box.h mem.h rom.h pci.h \ + device.h chipset/chipset.h disk/hdc.h disk/hdc_ide.h keyboard.h \ + intel_flash.h intel_sio.h piix.h sio.h sst_flash.h via_vt82c586b.h \ + video/video.h machine/machine.h diff --git a/src/m_at_socket8.d b/src/m_at_socket8.d new file mode 100644 index 000000000..37c74dcc3 --- /dev/null +++ b/src/m_at_socket8.d @@ -0,0 +1,4 @@ +m_at_socket8.o: machine/m_at_socket8.c 86box.h mem.h 86box_io.h rom.h \ + pci.h device.h chipset/chipset.h disk/hdc.h disk/hdc_ide.h keyboard.h \ + intel_flash.h intel_sio.h piix.h sio.h sst_flash.h video/video.h \ + machine/machine.h diff --git a/src/m_at_t3100e.d b/src/m_at_t3100e.d new file mode 100644 index 000000000..f6ec0922e --- /dev/null +++ b/src/m_at_t3100e.d @@ -0,0 +1,3 @@ +m_at_t3100e.o: machine/m_at_t3100e.c 86box.h timer.h cpu_common/cpu.h \ + 86box_io.h mouse.h mem.h device.h keyboard.h rom.h floppy/fdd.h \ + floppy/fdc.h machine/machine.h machine/m_at_t3100e.h diff --git a/src/m_at_t3100e_vid.d b/src/m_at_t3100e_vid.d new file mode 100644 index 000000000..aac5965ce --- /dev/null +++ b/src/m_at_t3100e_vid.d @@ -0,0 +1,3 @@ +m_at_t3100e_vid.o: machine/m_at_t3100e_vid.c 86box.h device.h 86box_io.h \ + mem.h timer.h cpu_common/cpu.h video/video.h video/vid_cga.h \ + machine/m_at_t3100e.h diff --git a/src/m_europc.d b/src/m_europc.d new file mode 100644 index 000000000..2fd6414c3 --- /dev/null +++ b/src/m_europc.d @@ -0,0 +1,4 @@ +m_europc.o: machine/m_europc.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h nmi.h mem.h pit.h rom.h device.h nvr.h keyboard.h \ + mouse.h game/gameport.h floppy/fdd.h floppy/fdc.h disk/hdc.h \ + video/video.h machine/machine.h diff --git a/src/m_olivetti_m24.d b/src/m_olivetti_m24.d new file mode 100644 index 000000000..20bacbba3 --- /dev/null +++ b/src/m_olivetti_m24.d @@ -0,0 +1,4 @@ +m_olivetti_m24.o: machine/m_olivetti_m24.c 86box.h timer.h \ + cpu_common/cpu.h 86box_io.h pic.h pit.h ppi.h nmi.h mem.h device.h nvr.h \ + keyboard.h mouse.h rom.h floppy/fdd.h floppy/fdc.h game/gameport.h \ + sound/sound.h sound/snd_speaker.h video/video.h machine/machine.h diff --git a/src/m_pcjr.d b/src/m_pcjr.d new file mode 100644 index 000000000..09fe478ad --- /dev/null +++ b/src/m_pcjr.d @@ -0,0 +1,4 @@ +m_pcjr.o: machine/m_pcjr.c 86box.h cpu_common/cpu.h timer.h 86box_io.h \ + nmi.h pic.h pit.h mem.h device.h serial.h keyboard.h rom.h floppy/fdd.h \ + floppy/fdc.h sound/sound.h sound/snd_speaker.h sound/snd_sn76489.h \ + video/video.h video/vid_cga_comp.h machine/machine.h diff --git a/src/m_ps1.d b/src/m_ps1.d new file mode 100644 index 000000000..efff60775 --- /dev/null +++ b/src/m_ps1.d @@ -0,0 +1,4 @@ +m_ps1.o: machine/m_ps1.c 86box.h cpu_common/cpu.h timer.h 86box_io.h \ + dma.h pic.h pit.h mem.h nmi.h rom.h device.h nvr.h game/gameport.h lpt.h \ + serial.h keyboard.h disk/hdc.h disk/hdc_ide.h floppy/fdd.h floppy/fdc.h \ + sound/sound.h sound/snd_sn76489.h video/video.h machine/machine.h diff --git a/src/m_ps1_hdc.d b/src/m_ps1_hdc.d new file mode 100644 index 000000000..13321d7f9 --- /dev/null +++ b/src/m_ps1_hdc.d @@ -0,0 +1,3 @@ +m_ps1_hdc.o: machine/m_ps1_hdc.c 86box.h timer.h cpu_common/cpu.h \ + 86box_io.h dma.h pic.h device.h disk/hdc.h disk/hdd.h plat.h \ + lang/language.h ui.h machine/machine.h diff --git a/src/m_ps2_isa.d b/src/m_ps2_isa.d new file mode 100644 index 000000000..578337dde --- /dev/null +++ b/src/m_ps2_isa.d @@ -0,0 +1,4 @@ +m_ps2_isa.o: machine/m_ps2_isa.c 86box.h cpu_common/cpu.h timer.h \ + 86box_io.h dma.h pic.h pit.h mem.h rom.h device.h nvr.h keyboard.h lpt.h \ + port_92.h serial.h disk/hdc.h floppy/fdd.h floppy/fdc.h video/video.h \ + machine/machine.h diff --git a/src/m_ps2_mca.d b/src/m_ps2_mca.d new file mode 100644 index 000000000..0480f83ce --- /dev/null +++ b/src/m_ps2_mca.d @@ -0,0 +1,4 @@ +m_ps2_mca.o: machine/m_ps2_mca.c 86box.h cpu_common/cpu.h \ + cpu_common/x86.h timer.h 86box_io.h dma.h pic.h pit.h mca.h mem.h nmi.h \ + rom.h device.h floppy/fdd.h floppy/fdc.h nvr.h nvr_ps2.h keyboard.h \ + lpt.h mouse.h port_92.h serial.h video/video.h machine/machine.h diff --git a/src/m_tandy.d b/src/m_tandy.d new file mode 100644 index 000000000..8d7b54307 --- /dev/null +++ b/src/m_tandy.d @@ -0,0 +1,4 @@ +m_tandy.o: machine/m_tandy.c 86box.h timer.h cpu_common/cpu.h 86box_io.h \ + pit.h nmi.h mem.h rom.h device.h nvr.h floppy/fdd.h floppy/fdc.h \ + game/gameport.h keyboard.h sound/sound.h sound/snd_sn76489.h \ + video/video.h video/vid_cga_comp.h machine/machine.h diff --git a/src/m_xt.d b/src/m_xt.d new file mode 100644 index 000000000..a6c9cc780 --- /dev/null +++ b/src/m_xt.d @@ -0,0 +1,3 @@ +m_xt.o: machine/m_xt.c 86box.h nmi.h timer.h cpu_common/cpu.h pit.h mem.h \ + device.h floppy/fdd.h floppy/fdc.h game/gameport.h ibm_5161.h keyboard.h \ + rom.h machine/machine.h diff --git a/src/m_xt_compaq.d b/src/m_xt_compaq.d new file mode 100644 index 000000000..9f498bb61 --- /dev/null +++ b/src/m_xt_compaq.d @@ -0,0 +1,3 @@ +m_xt_compaq.o: machine/m_xt_compaq.c 86box.h cpu_common/cpu.h nmi.h \ + timer.h pit.h mem.h rom.h device.h floppy/fdd.h floppy/fdc.h \ + game/gameport.h keyboard.h lpt.h machine/machine.h diff --git a/src/m_xt_t1000.d b/src/m_xt_t1000.d new file mode 100644 index 000000000..1bf4bc19a --- /dev/null +++ b/src/m_xt_t1000.d @@ -0,0 +1,4 @@ +m_xt_t1000.o: machine/m_xt_t1000.c 86box.h cpu_common/cpu.h 86box_io.h \ + timer.h pit.h nmi.h mem.h rom.h device.h nvr.h keyboard.h lpt.h \ + floppy/fdd.h floppy/fdc.h game/gameport.h video/video.h plat.h \ + lang/language.h machine/machine.h machine/m_xt_t1000.h diff --git a/src/m_xt_t1000_vid.d b/src/m_xt_t1000_vid.d new file mode 100644 index 000000000..01cadf1f2 --- /dev/null +++ b/src/m_xt_t1000_vid.d @@ -0,0 +1,3 @@ +m_xt_t1000_vid.o: machine/m_xt_t1000_vid.c 86box.h device.h 86box_io.h \ + mem.h timer.h cpu_common/cpu.h video/video.h video/vid_cga.h \ + machine/m_xt_t1000.h diff --git a/src/m_xt_xi8088.d b/src/m_xt_xi8088.d new file mode 100644 index 000000000..1b42e22d1 --- /dev/null +++ b/src/m_xt_xi8088.d @@ -0,0 +1,4 @@ +m_xt_xi8088.o: machine/m_xt_xi8088.c 86box.h timer.h cpu_common/cpu.h \ + pic.h pit.h dma.h mem.h device.h floppy/fdd.h floppy/fdc.h nmi.h nvr.h \ + game/gameport.h keyboard.h lpt.h rom.h disk/hdc.h video/video.h \ + machine/machine.h machine/m_xt_xi8088.h machine/../device.h diff --git a/src/m_xt_zenith.d b/src/m_xt_zenith.d new file mode 100644 index 000000000..15025d887 --- /dev/null +++ b/src/m_xt_zenith.d @@ -0,0 +1,3 @@ +m_xt_zenith.o: machine/m_xt_zenith.c 86box.h cpu_common/cpu.h timer.h \ + dma.h nmi.h pic.h pit.h mem.h rom.h device.h floppy/fdd.h floppy/fdc.h \ + game/gameport.h keyboard.h lpt.h serial.h machine/machine.h diff --git a/src/machine.d b/src/machine.d new file mode 100644 index 000000000..47a2fc9bf --- /dev/null +++ b/src/machine.d @@ -0,0 +1,3 @@ +machine.o: machine/machine.c 86box.h device.h timer.h cpu_common/cpu.h \ + dma.h pic.h pit.h mem.h rom.h lpt.h serial.h video/video.h \ + machine/machine.h diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 3ebfee31a..d2c4325e3 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -48,31 +48,30 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../ppi.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../game/gameport.h" -#include "../lpt.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../sound/sound.h" -#include "../sound/snd_speaker.h" -#include "../video/video.h" -#include "../video/vid_cga.h" -#include "../video/vid_ega.h" -#include "../video/vid_mda.h" -#include "../video/vid_paradise.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "nmi.h" +#include "pic.h" +#include "pit.h" +#include "ppi.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "mouse.h" +#include "gameport.h" +#include "lpt.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" +#include "vid_cga.h" +#include "vid_ega.h" +#include "vid_mda.h" #include "machine.h" #include "m_amstrad.h" diff --git a/src/machine/m_at.c b/src/machine/m_at.c index ca93a489e..25666f7bc 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -40,21 +40,21 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../pic.h" -#include "../pit.h" -#include "../dma.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../nvr.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../rom.h" -#include "../disk/hdc.h" +#include "86box.h" +#include "timer.h" +#include "pic.h" +#include "pit.h" +#include "dma.h" +#include "mem.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "nvr.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" +#include "rom.h" +#include "hdc.h" #include "machine.h" diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 95b7ee98d..70c78226b 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -22,23 +22,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../rom.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_et4000.h" -#include "../video/vid_oak_oti.h" -#include "../video/vid_paradise.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "device.h" +#include "chipset.h" +#include "keyboard.h" +#include "mem.h" +#include "rom.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "video.h" #include "machine.h" @@ -224,6 +220,26 @@ machine_at_goldstar386_init(const machine_t *model) return ret; } +int +machine_at_micronics386_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", + L"roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", + 0x000f0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + + device_add(&neat_device); + device_add(&fdc_at_device); + + return ret; +} + static void machine_at_scat_init(const machine_t *model, int is_v4) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 1efd3ee12..78562d82f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -22,25 +22,24 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../keyboard.h" -#include "../mem.h" -#include "../nvr.h" -#include "../pci.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../rom.h" -#include "../sio.h" -#include "../disk/hdc.h" -#include "../video/video.h" -#include "../video/vid_ht216.h" -#include "../intel_flash.h" -#include "../intel_sio.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "device.h" +#include "chipset.h" +#include "keyboard.h" +#include "mem.h" +#include "nvr.h" +#include "pci.h" +#include "fdd.h" +#include "fdc.h" +#include "rom.h" +#include "sio.h" +#include "hdc.h" +#include "video.h" +#include "intel_flash.h" +#include "intel_sio.h" #include "machine.h" @@ -68,24 +67,6 @@ machine_at_pb410a_init(const machine_t *model) return ret; } -int -machine_at_micronics386_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved(L"roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", - L"roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", - 0x000f0000, 131072, 0); - - if (bios_only || !ret) - return ret; - - machine_at_init(model); - device_add(&keyboard_at_device); - device_add(&fdc_at_device); - - return ret; -} static void machine_at_ali1429_common_init(const machine_t *model) @@ -288,10 +269,10 @@ machine_at_win471_init(const machine_t *model) static void machine_at_sis_85c496_common_init(const machine_t *model) { - device_add(&ide_pci_device); + device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -352,6 +333,29 @@ machine_at_ls486e_init(const machine_t *model) } +int +machine_at_4dps_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/4dps/4DPS172G.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + machine_at_sis_85c496_common_init(model); + pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&w83787f_device); + device_add(&keyboard_ps2_pci_device); + + return ret; +} + + int machine_at_alfredo_init(const machine_t *model) { @@ -367,12 +371,12 @@ machine_at_alfredo_init(const machine_t *model) device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&sio_device); device_add(&fdc37c663_device); @@ -382,3 +386,35 @@ machine_at_alfredo_init(const machine_t *model) return ret; } + + +int +machine_at_486sp3g_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/486sp3g/PCI-I-486SP3G_0306.001 (Beta).bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&ide_pci_2ch_device); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&keyboard_ps2_pci_device); + device_add(&sio_device); /* Site says it has a ZB, but the BIOS is designed for an IB. */ + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420zx_device); + + return ret; +} diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index 348c43e36..066a8ab7a 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -40,16 +40,16 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../io.h" -#include "../mem.h" -#include "../lpt.h" -#include "../rom.h" -#include "../serial.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "86box_io.h" +#include "mem.h" +#include "lpt.h" +#include "rom.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" #include "machine.h" diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 801de3412..ac8175b27 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -21,16 +21,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "hdc_ide.h" #include "machine.h" diff --git a/src/machine/m_at_socket4_5.c b/src/machine/m_at_socket4_5.c index 7053eef6b..15012e856 100644 --- a/src/machine/m_at_socket4_5.c +++ b/src/machine/m_at_socket4_5.c @@ -21,26 +21,24 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../keyboard.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../piix.h" -#include "../sio.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "chipset.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "keyboard.h" +#include "intel_flash.h" +#include "intel_sio.h" +#include "piix.h" +#include "sio.h" +#include "video.h" #include "machine.h" @@ -51,12 +49,12 @@ machine_at_premiere_common_init(const machine_t *model) device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&sio_zb_device); device_add(&fdc37c665_device); @@ -71,14 +69,14 @@ machine_at_award_common_init(const machine_t *model) device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0); pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ - pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&fdc_at_device); device_add(&keyboard_ps2_pci_device); device_add(&sio_device); @@ -236,12 +234,12 @@ machine_at_p54tp4xe_init(const machine_t *model) /* Award BIOS, SMC FDC37C665. */ pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -266,13 +264,13 @@ machine_at_endeavor_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); if (gfxcard == VID_INTERNAL) device_add(&s3_phoenix_trio64_onboard_pci_device); @@ -308,11 +306,11 @@ machine_at_zappa_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -337,12 +335,12 @@ machine_at_mb500n_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_pci_device); device_add(&i430fx_device); device_add(&piix_device); @@ -367,12 +365,12 @@ machine_at_president_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430fx_device); device_add(&piix_device); device_add(&keyboard_ps2_pci_device); @@ -398,12 +396,12 @@ machine_at_vectra54_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&keyboard_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index a281b69c0..9db6c31cc 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -8,7 +8,7 @@ * * Implementation of Socket 7 and Super Socket 7 machines. * - * Version: @(#)m_at_socket7_s7.c 1.0.2 2020/01/18 + * Version: @(#)m_at_socket7_s7.c 1.0.3 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, @@ -23,25 +23,23 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../piix.h" -#include "../sio.h" -#include "../sst_flash.h" -#include "../via_vt82c586b.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" +#include "86box.h" +#include "mem.h" +#include "io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "chipset.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "keyboard.h" +#include "intel_flash.h" +#include "intel_sio.h" +#include "piix.h" +#include "sio.h" +#include "sst_flash.h" +#include "via_vt82c586b.h" +#include "video.h" #include "machine.h" @@ -51,13 +49,13 @@ machine_at_thor_common_init(const machine_t *model, int mr) machine_at_common_init_ex(model, mr); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430fx_device); device_add(&piix_device); device_add(&keyboard_ps2_ami_pci_device); @@ -116,12 +114,12 @@ machine_at_pb640_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430fx_pb640_device); device_add(&piix_pb640_device); device_add(&ide_isa_2ch_device); @@ -158,8 +156,8 @@ machine_at_acerm3a_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -191,8 +189,8 @@ machine_at_acerv35n_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -224,12 +222,12 @@ machine_at_ap53_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); @@ -255,12 +253,12 @@ machine_at_p55t2p4_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -285,12 +283,12 @@ machine_at_p55t2s_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -317,25 +315,26 @@ machine_at_tc430hx_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); device_add(&pc87306_device); - device_add(&intel_flash_bxtw_ami_device); + device_add(&intel_flash_bxt_ami_device); return ret; } + int machine_at_equium5200_init(const machine_t *model) // Information about that machine on machine.h { @@ -354,13 +353,13 @@ machine_at_equium5200_init(const machine_t *model) // Information about that mac machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser device_add(&i430hx_device); device_add(&piix3_device); device_add(&keyboard_ps2_ami_pci_device); @@ -387,12 +386,12 @@ machine_at_p55tvp4_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -417,12 +416,12 @@ machine_at_i430vx_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -447,12 +446,12 @@ machine_at_p55va_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -477,11 +476,11 @@ machine_at_j656vxd_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -491,6 +490,138 @@ machine_at_j656vxd_init(const machine_t *model) return ret; } + +int +machine_at_5tx52_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/5tx52/5itw002.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83877tf_acorp_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_txp4_init(const machine_t *model) +{ + int ret; + +#if 0 + ret = bios_load_linear(L"roms/machines/txp4/5itw003.bin", + 0x000e0000, 131072, 0); +#else + ret = bios_load_linear(L"roms/machines/txp4/TX5I0108.AWD", + 0x000e0000, 131072, 0); +#endif + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_ym430tx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ym430tx/YM430TX.003", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + +int +machine_at_sp586tx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/sp586tx/Txa6-32gb.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i430tx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977tf_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + + int machine_at_mvp3_init(const machine_t *model) { @@ -505,12 +636,12 @@ machine_at_mvp3_init(const machine_t *model) machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0a, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_mvp3_device); device_add(&via_vt82c586b_device); device_add(&keyboard_ps2_pci_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 18e4355c0..c6e08bacc 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -19,23 +19,22 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../io.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../chipset/chipset.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../keyboard.h" -#include "../intel_flash.h" -#include "../intel_sio.h" -#include "../piix.h" -#include "../sio.h" -#include "../video/video.h" -#include "../video/vid_cl54xx.h" -#include "../video/vid_s3.h" +#include "86box.h" +#include "mem.h" +#include "86box_io.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "chipset.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "keyboard.h" +#include "intel_flash.h" +#include "intel_sio.h" +#include "piix.h" +#include "sio.h" +#include "sst_flash.h" +#include "video.h" #include "machine.h" @@ -56,13 +55,13 @@ machine_at_i440fx_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i440fx_device); device_add(&piix3_device); device_add(&keyboard_ps2_pci_device); @@ -87,8 +86,8 @@ machine_at_s1668_init(const machine_t *model) machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -104,4 +103,38 @@ machine_at_s1668_init(const machine_t *model) } +int +machine_at_ax6bc_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ax6bc/QS440BX 2M_2.10.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83877tf_device); + // device_add(&w83977tf_device); + // device_add(&intel_flash_bxt_device); + // device_add(&sst_flash_29ee020_device); + device_add(&sst_flash_39sf020_device); + + return ret; +} + + #endif diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 6d25453b6..4244a96e5 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -152,17 +152,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../mouse.h" -#include "../mem.h" -#include "../device.h" -#include "../keyboard.h" -#include "../rom.h" -#include "../cpu/cpu.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "mouse.h" +#include "mem.h" +#include "device.h" +#include "keyboard.h" +#include "rom.h" +#include "cpu.h" +#include "fdd.h" +#include "fdc.h" #include "machine.h" #include "m_at_t3100e.h" diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index 683789a20..6f9f20200 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/machine/m_at_t3100e_vid.c @@ -57,14 +57,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../cpu/cpu.h" -#include "../video/video.h" -#include "../video/vid_cga.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "cpu.h" +#include "video.h" +#include "vid_cga.h" #include "m_at_t3100e.h" diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index c50fe6364..d642b0099 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -87,22 +87,22 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pit.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../game/gameport.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../disk/hdc.h" -#include "../video/video.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "nmi.h" +#include "mem.h" +#include "pit.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "mouse.h" +#include "gameport.h" +#include "fdd.h" +#include "fdc.h" +#include "hdc.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c index 9bb84198f..f2fef9bb8 100644 --- a/src/machine/m_olivetti_m24.c +++ b/src/machine/m_olivetti_m24.c @@ -24,25 +24,25 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../pic.h" -#include "../pit.h" -#include "../ppi.h" -#include "../nmi.h" -#include "../mem.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../rom.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../sound/sound.h" -#include "../sound/snd_speaker.h" -#include "../video/video.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "pic.h" +#include "pit.h" +#include "ppi.h" +#include "nmi.h" +#include "mem.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "mouse.h" +#include "rom.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "sound.h" +#include "snd_speaker.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index a5ff9cc8b..77628a800 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -26,25 +26,25 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" -#include "../serial.h" -#include "../keyboard.h" -#include "../rom.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../sound/sound.h" -#include "../sound/snd_speaker.h" -#include "../sound/snd_sn76489.h" -#include "../video/video.h" -#include "../video/vid_cga_comp.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "nmi.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "device.h" +#include "serial.h" +#include "keyboard.h" +#include "rom.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_speaker.h" +#include "snd_sn76489.h" +#include "video.h" +#include "vid_cga_comp.h" #include "machine.h" diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 9ff547d45..c8a3ee8b2 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -37,31 +37,29 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../game/gameport.h" -#include "../lpt.h" -#include "../serial.h" -#include "../keyboard.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../sound/sound.h" -#include "../sound/snd_sn76489.h" -#include "../video/video.h" -#include "../video/vid_vga.h" -#include "../video/vid_ti_cf62011.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "nmi.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "gameport.h" +#include "lpt.h" +#include "serial.h" +#include "keyboard.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" +#include "sound.h" +#include "snd_sn76489.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index 5c10ca69b..d767b7aa8 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -92,16 +92,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/hdd.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "device.h" +#include "hdc.h" +#include "hdd.h" +#include "plat.h" +#include "ui.h" #include "machine.h" diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index a713278d9..fe6d3e6c4 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -2,25 +2,25 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../port_92.h" -#include "../serial.h" -#include "../disk/hdc.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../video/vid_vga.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "lpt.h" +#include "port_92.h" +#include "serial.h" +#include "hdc.h" +#include "fdd.h" +#include "fdc.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 7eb011931..c4b755a6d 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -42,35 +42,29 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#ifdef USE_NEW_DYNAREC -#include "../cpu_new/cpu.h" -#include "../cpu_new/x86.h" -#else -#include "../cpu/cpu.h" -#include "../cpu/x86.h" -#endif -#include "../timer.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mca.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../nvr.h" -#include "../nvr_ps2.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../mouse.h" -#include "../port_92.h" -#include "../serial.h" -#include "../video/video.h" -#include "../video/vid_vga.h" +#include "86box.h" +#include "cpu.h" +#include "x86.h" +#include "timer.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mca.h" +#include "mem.h" +#include "nmi.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "nvr.h" +#include "nvr_ps2.h" +#include "keyboard.h" +#include "lpt.h" +#include "mouse.h" +#include "port_92.h" +#include "serial.h" +#include "video.h" #include "machine.h" diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index bbcf7786c..658f8c1f0 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -24,24 +24,23 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../io.h" -#include "../pit.h" -#include "../nmi.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../sound/sound.h" -#include "../sound/snd_pssj.h" -#include "../sound/snd_sn76489.h" -#include "../video/video.h" -#include "../video/vid_cga_comp.h" +#include "86box.h" +#include "timer.h" +#include "86box_io.h" +#include "pit.h" +#include "nmi.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" +#include "sound.h" +#include "snd_sn76489.h" +#include "video.h" +#include "vid_cga_comp.h" #include "machine.h" diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index c3bf07897..ec9cd1da6 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -2,18 +2,18 @@ #include #include #include -#include "../86box.h" -#include "../nmi.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../ibm_5161.h" -#include "../keyboard.h" -#include "../rom.h" +#include "86box.h" +#include "nmi.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "ibm_5161.h" +#include "keyboard.h" +#include "rom.h" #include "machine.h" diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index 1e312fe10..edc3cf007 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -21,19 +21,19 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../nmi.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" +#include "86box.h" +#include "cpu.h" +#include "nmi.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" #include "machine.h" diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index f8408952e..41416769c 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -3,21 +3,21 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../nmi.h" -#include "../timer.h" -#include "../pit.h" -#include "../rom.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "nmi.h" +#include "timer.h" +#include "pit.h" +#include "rom.h" #include "machine.h" -#include "../device.h" -#include "../timer.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" +#include "device.h" +#include "timer.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" static int laserxt_emspage[4]; diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index ee9bb8cd0..2e8fd40f9 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -87,24 +87,24 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../nmi.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../mem.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../video/video.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "nmi.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "keyboard.h" +#include "lpt.h" +#include "mem.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "video.h" +#include "plat.h" #include "machine.h" #include "m_xt_t1000.h" diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 1e2d62e13..8196e8e59 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -42,14 +42,14 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../cpu/cpu.h" -#include "../video/video.h" -#include "../video/vid_cga.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "cpu.h" +#include "video.h" +#include "vid_cga.h" #include "m_xt_t1000.h" diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 162b6da11..42b0d2498 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -2,25 +2,25 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../pic.h" -#include "../pit.h" -#include "../dma.h" -#include "../mem.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../nmi.h" -#include "../nvr.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../rom.h" -#include "../disk/hdc.h" -#include "../video/video.h" +#include "86box.h" +#include "timer.h" +#include "pic.h" +#include "pit.h" +#include "dma.h" +#include "mem.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "nmi.h" +#include "nvr.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" +#include "rom.h" +#include "hdc.h" +#include "video.h" #include "machine.h" -#include "../cpu/cpu.h" +#include "cpu.h" #include "m_xt_xi8088.h" diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 23b44199d..d6b1b5261 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -24,22 +24,22 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../timer.h" -#include "../dma.h" -#include "../nmi.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../floppy/fdd.h" -#include "../floppy/fdc.h" -#include "../game/gameport.h" -#include "../keyboard.h" -#include "../lpt.h" -#include "../serial.h" +#include "86box.h" +#include "cpu.h" +#include "timer.h" +#include "dma.h" +#include "nmi.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "fdd.h" +#include "fdc.h" +#include "gameport.h" +#include "keyboard.h" +#include "lpt.h" +#include "serial.h" #include "machine.h" diff --git a/src/machine/machine.c b/src/machine/machine.c index c2f19bd47..d5a5680b1 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -8,15 +8,15 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.c 1.0.38 2019/11/15 + * Version: @(#)machine.c 1.0.39 2020/01/24 * * 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-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -24,18 +24,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../lpt.h" -#include "../serial.h" -#include "../cpu/cpu.h" -#include "../video/video.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "cpu.h" +#include "video.h" #include "machine.h" @@ -81,6 +81,8 @@ machine_init_ex(int m) mem_reset(); lpt_init(); + + smbase = 0x30000; } /* All good, boot the machine! */ diff --git a/src/machine/machine.h b/src/machine/machine.h index 6e03f707a..c0a59a7b6 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.37 2020/01/22 + * Version: @(#)machine.h 1.0.38 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, @@ -190,6 +190,7 @@ extern int machine_at_neat_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *); extern int machine_at_goldstar386_init(const machine_t *); +extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_award286_init(const machine_t *); @@ -210,7 +211,6 @@ extern const device_t *at_commodore_sl386sx_get_device(void); /* m_at_386dx_486.c */ extern int machine_at_pb410a_init(const machine_t *); -extern int machine_at_micronics386_init(const machine_t *); extern int machine_at_ali1429_init(const machine_t *); extern int machine_at_winbios1429_init(const machine_t *); @@ -228,7 +228,9 @@ extern int machine_at_win471_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); +extern int machine_at_4dps_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); +extern int machine_at_486sp3g_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); @@ -287,6 +289,11 @@ extern int machine_at_i430vx_init(const machine_t *); extern int machine_at_p55va_init(const machine_t *); extern int machine_at_j656vxd_init(const machine_t *); +extern int machine_at_5tx52_init(const machine_t *); +extern int machine_at_txp4_init(const machine_t *); +extern int machine_at_ym430tx_init(const machine_t *); +extern int machine_at_sp586tx_init(const machine_t *); + extern int machine_at_mvp3_init(const machine_t *); #ifdef EMU_DEVICE_H @@ -297,6 +304,8 @@ extern const device_t *at_pb640_get_device(void); #if defined(DEV_BRANCH) && defined(USE_I686) extern int machine_at_i440fx_init(const machine_t *); extern int machine_at_s1668_init(const machine_t *); + +extern int machine_at_ax6bc_init(const machine_t *); #endif /* m_at_t3100e.c */ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 18fc0cf36..f0a2cfedc 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.54 2020/01/22 + * Version: @(#)machine_table.c 1.0.55 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, @@ -25,14 +25,20 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "machine.h" +#ifdef USE_NEW_DYNAREC +#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"Cyrix", cpus_6x863V}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}} +#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}} +#else #if defined(DEV_BRANCH) && defined(USE_AMD_K) #define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) @@ -52,6 +58,9 @@ #define MACHINE_CPUS_PENTIUM_S7 {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}} #endif #endif +#define MACHINE_CPUS_PENTIUM_SS7 MACHINE_CPUS_PENTIUM_S7 +#endif + const machine_t machines[] = { { "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, @@ -76,7 +85,7 @@ const machine_t machines[] = { { "[8088] Xi8088", "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, { "[8088] Zenith Data SupersPort", "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, - { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, + { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, { "[8086] Amstrad PC1640", "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device }, { "[8086] Amstrad PC2086", "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device }, { "[8086] Amstrad PC3086", "pc3086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, @@ -118,8 +127,8 @@ const machine_t machines[] = { { "[286 ISA] Toshiba T3100e", "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, { "[286 ISA] Trigem 286M", "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, - { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, - + { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, + { "[286 MCA] IBM PS/2 model 50", "ibmps2_m50", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, { "[386SX ISA] AMA-932J", "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, @@ -127,105 +136,108 @@ const machine_t machines[] = { { "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, #endif { "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, + { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, { "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL }, { "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] KMX-C-02", "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL }, { "[386SX ISA] Goldstar 386", "goldstar386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL }, + { "[386SX ISA] Micronics 09-00021", "micronics386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, + { "[386SX MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, - { "[386DX ISA] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, { "[386DX ISA] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX ISA] Micronics 09-00021", "micronics386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_micronics386_init, NULL }, + { "[386DX ISA] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_MR495) { "[386DX ISA] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, #endif #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) { "[386DX ISA] Compaq Portable III (386)", "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 14, 1, 127, machine_at_portableiii386_init, NULL }, #endif - { "[386DX VLB] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX VLB] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[386DX VLB] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif + { "[386DX MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, { "[386DX MCA] IBM PS/2 model 80", "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, - { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, - - { "[486 VLB] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[486 VLB] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[486 ISA] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, + { "[486 ISA] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, + { "[486 ISA] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, + { "[486 ISA] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, + { "[486 ISA] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, + { "[486 ISA] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, + { "[486 ISA] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PS1M2133) - { "[486 VLB] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, + { "[486 ISA] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, #endif - { "[486 VLB] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, - - { "[486 VLB] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, - { "[486 VLB] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, - { "[486 VLB] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, - { "[486 VLB] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, - #if defined(DEV_BRANCH) && defined(USE_MR495) - { "[486 VLB] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, + { "[486 ISA] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, #endif - { "[486 VLB] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, + { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 64, 1, 127, machine_at_pb410a_init, NULL }, + { "[486 ISA] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PS2M70T4) { "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, #endif - { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, - { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, - { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, + { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, + { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_ls486e_init, NULL }, + { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, + { "[486 PCI] Zida 4DPS", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, + { "[486 PCI] ASUS P/I-486SP3G", "486sp3g", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_486sp3g_init, NULL }, - { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, + { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, + { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VPP60) - { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, + { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, #endif - { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, + { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, - { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, - { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, + { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, + { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, + { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, - { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, + { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_VECTRA54) - { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_vectra54_init, NULL }, + { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 255, machine_at_vectra54_init, NULL }, #endif - { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, - { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, - { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, + { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, + { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, + { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, - { "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, + { "[Socket 7 FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_MRTHOR) - { "[Socket 7-3V FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, + { "[Socket 7 FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, #endif - { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, - { "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, - - { "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, - { "[Socket 7-3V HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, - { "[Socket 7-3V HX] SuperMicro Super P55T2S","p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, + { "[Socket 7 FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, + { "[Socket 7 FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, + + { "[Socket 7 HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, + { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, + { "[Socket 7 HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, + { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, + { "[Socket 7 HX] SuperMicro Super P55T2S", "p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_TC430HX) - { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_tc430hx_init, NULL }, - { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, + { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL }, + { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, #endif - { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, - { "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL }, - { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, + { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, + { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, + { "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL }, + { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - { "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_mvp3_init, NULL }, + { "[Socket 7 TX] Acorp 5TX52", "5tx52", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_5tx52_init, NULL }, + { "[Socket 7 TX] ASUS TXP4", "txp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_txp4_init, NULL }, + { "[Socket 7 TX] Intel YM430TX", "ym430tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_ym430tx_init, NULL }, + { "[Socket 7 TX] San-LI/Superpower SP-586TX","sp586tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_sp586tx_init, NULL }, + + { "[Super Socket 7] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_I686) { "[Socket 8 FX] Tyan Titan-Pro AT", "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL }, { "[Socket 8 FX] Tyan Titan-Pro ATX", "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL }, + + { "[Slot 1 FX] AOpen AX6BC", "ax6bc", {{"Intel", cpus_PentiumII}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_ax6bc_init, NULL }, #endif { NULL, NULL, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } }; diff --git a/src/machine/machine_table_new.c b/src/machine/machine_table_new.c deleted file mode 100644 index e51885bf4..000000000 --- a/src/machine/machine_table_new.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Handling of the emulated machines. - * - * 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.54 2020/01/22 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include "../86box.h" -#include "../cpu_new/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "machine.h" - - -#define MACHINE_CPUS_PENTIUM_S5 {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}} -#define MACHINE_CPUS_PENTIUM_S73V {{ "Intel", cpus_Pentium3V}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"Cyrix", cpus_6x863V}, {"", NULL}} -#define MACHINE_CPUS_PENTIUM_S7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86}, {"", NULL}} -#define MACHINE_CPUS_PENTIUM_SS7 {{ "Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"AMD", cpus_K56_SS7}, {"Cyrix", cpus_6x86SS7}, {"", NULL}} - -const machine_t machines[] = { - { "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, - { "[8088] Compaq Portable", "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, - { "[8088] DTK XT clone", "dtk", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, - { "[8088] IBM PC (1981)", "ibmpc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 16, 64, 16, 0, machine_pc_init, NULL }, - { "[8088] IBM PC (1982)", "ibmpc82", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 256, 256, 0, machine_pc82_init, NULL }, - { "[8088] IBM PCjr", "ibmpcjr", {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, - { "[8088] IBM XT (1982)", "ibmxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 256, 64, 0, machine_xt_init, NULL }, - { "[8088] IBM XT (1986)", "ibmxt86", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 64, 0, machine_xt86_init, NULL }, - { "[8088] Generic XT clone", "genxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_genxt_init, NULL }, - { "[8088] Juko XT clone", "jukopc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, - { "[8088] OpenXT", "open_xt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_open_xt_init, NULL }, - { "[8088] Phoenix XT clone", "pxxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_pxxt_init, NULL }, - { "[8088] Schneider EuroPC", "europc", {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_HDC | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, - { "[8088] Tandy 1000", "tandy", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device }, - { "[8088] Tandy 1000 HX", "tandy1000hx", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device }, - { "[8088] Toshiba T1000", "t1000", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 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", "ltxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_laserxt_init, NULL }, -#endif - { "[8088] Xi8088", "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device }, - { "[8088] Zenith Data SupersPort", "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, - - { "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, - { "[8086] Amstrad PC1640", "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device }, - { "[8086] Amstrad PC2086", "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device }, - { "[8086] Amstrad PC3086", "pc3086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, - { "[8086] Amstrad PC20(0)", "pc200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device }, - { "[8086] Amstrad PPC512/640", "ppc512", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device }, - { "[8086] Olivetti M24", "olivetti_m24", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, - { "[8086] Tandy 1000 SL/2", "tandy1000sl2", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, NULL }, - { "[8086] Toshiba T1200", "t1200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 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", "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, -#endif - - { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, - { "[286 ISA] Phoenix 286 clone", "px286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL }, - { "[286 ISA] Quadtel 286 clone", "quadt286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_quadt286_init, NULL }, - { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, - { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[286 ISA] Compaq Portable III", "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 640,16384, 128, 127, machine_at_portableiii_init, NULL }, -#endif - { "[286 ISA] GW-286CT GEAR", "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_gw286ct_init, NULL }, - { "[286 ISA] Hyundai Super-286TR", "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_super286tr_init, NULL }, - { "[286 ISA] IBM AT", "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL }, - { "[286 ISA] AMI IBM AT", "ibmatami", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatami_init, NULL }, - { "[286 ISA] Quadtel IBM AT", "ibmatquadtel", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatquadtel_init, NULL }, - { "[286 ISA] Phoenix IBM AT", "ibmatpx", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibmatpx_init, NULL }, - { "[286 ISA] IBM PS/1 model 2011", "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 512,16384, 512, 63, machine_ps1_m2011_init, NULL }, - { "[286 ISA] IBM PS/2 model 30-286", "ibmps2_m30_286", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC | MACHINE_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL }, - { "[286 ISA] IBM XT Model 286", "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 127, machine_at_ibmxt286_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_SIEMENS) - { "[286 ISA] Siemens PCD-2L", "siemens", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_siemens_init, NULL }, -#endif -#if defined(DEV_BRANCH) && defined(USE_OPEN_AT) - { "[286 ISA] OpenAT", "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_open_at_init, NULL }, -#endif - { "[286 ISA] Samsung SPC-4200P", "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, - { "[286 ISA] Samsung SPC-4216P", "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_spc4216p_init, NULL }, - { "[286 ISA] Toshiba T3100e", "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, - { "[286 ISA] Trigem 286M", "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, - - { "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL }, - - { "[286 MCA] IBM PS/2 model 50", "ibmps2_m50", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, - - { "[386SX ISA] AMA-932J", "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, -#if defined(DEV_BRANCH) && defined(USE_AMI386SX) - { "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, -#endif - { "[386SX ISA] Amstrad MegaPC", "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, - { "[386SX ISA] Commodore SL386SX", "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, - { "[386SX ISA] DTK 386SX clone", "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_neat_init, NULL }, - { "[386SX ISA] IBM PS/1 model 2121", "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, - { "[386SX ISA] KMX-C-02", "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_kmxc02_init, NULL }, - - { "[386SX ISA] Goldstar 386", "goldstar386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL }, - { "[386SX MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL }, - - { "[386DX ISA] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[386DX ISA] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX ISA] Micronics 09-00021", "micronics386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_micronics386_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[386DX ISA] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif -#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) - { "[386DX ISA] Compaq Portable III (386)", "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 1, 14, 1, 127, machine_at_portableiii386_init, NULL }, -#endif - - { "[386DX VLB] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, - { "[386DX VLB] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[386DX VLB] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif - - { "[386DX MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL }, - { "[386DX MCA] IBM PS/2 model 80", "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL }, - - { "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, - - { "[486 VLB] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, - { "[486 VLB] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_PS1M2133) - { "[486 VLB] IBM PS/1 model 2133", "ibmps1_2133", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_NONMI, 1, 64, 1, 127, machine_ps1_m2133_init, NULL }, -#endif - { "[486 VLB] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL }, - - { "[486 VLB] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL }, - { "[486 VLB] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL }, - { "[486 VLB] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL }, - { "[486 VLB] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MR495) - { "[486 VLB] MR 486 clone", "mr486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, -#endif - { "[486 VLB] Phoenix SiS 471", "px471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_px471_init, NULL }, - -#if defined(DEV_BRANCH) && defined(USE_PS2M70T4) - { "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL }, -#endif - - { "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL }, - { "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL }, - { "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL }, - - { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_VPP60) - { "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL }, -#endif - { "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL }, - { "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL }, - - { "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL }, - { "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL }, - { "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL }, - - { "[Socket 5 FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_VECTRA54) - { "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_vectra54_init, NULL }, -#endif - { "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL }, - { "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL }, - { "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL }, - - { "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) - { "[Socket 7-3V FX] MR Intel Advanced/ATX", "mrthor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, -#endif - { "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, - { "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, - - { "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL }, - { "[Socket 7-3V HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL }, - { "[Socket 7-3V HX] SuperMicro Super P55T2S","p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL }, - { "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL }, - { "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL }, -#if defined(DEV_BRANCH) && defined(USE_TC430HX) - { "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_tc430hx_init, NULL }, - { "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_equium5200_init, NULL }, -#endif - - { "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL }, - { "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL }, - { "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL }, - { "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL }, - - { "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_mvp3_init, NULL }, - -#if defined(DEV_BRANCH) && defined(USE_I686) - { "[Socket 8 FX] Tyan Titan-Pro AT", "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL }, - { "[Socket 8 FX] Tyan Titan-Pro ATX", "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL }, -#endif - { NULL, NULL, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL } -}; - - -int -machine_count(void) -{ - return((sizeof(machines) / sizeof(machine)) - 1); -} - - -char * -machine_getname(void) -{ - return((char *)machines[machine].name); -} - - -char * -machine_getname_ex(int m) -{ - return((char *)machines[m].name); -} - - -const device_t * -machine_getdevice(int m) -{ - if (machines[m].get_device) - return(machines[m].get_device()); - - return(NULL); -} - - -char * -machine_get_internal_name(void) -{ - return((char *)machines[machine].internal_name); -} - - -char * -machine_get_internal_name_ex(int m) -{ - return((char *)machines[m].internal_name); -} - - -int -machine_get_nvrmask(int m) -{ - return(machines[m].nvrmask); -} - - -int -machine_get_machine_from_internal_name(char *s) -{ - int c = 0; - - while (machines[c].init != NULL) { - if (!strcmp(machines[c].internal_name, (const char *)s)) - return(c); - c++; - } - - return(0); -} diff --git a/src/machine_table.d b/src/machine_table.d new file mode 100644 index 000000000..c357609ea --- /dev/null +++ b/src/machine_table.d @@ -0,0 +1,2 @@ +machine_table.o: machine/machine_table.c 86box.h cpu_common/cpu.h mem.h \ + rom.h device.h machine/machine.h diff --git a/src/machine_table.txt b/src/machine_table.txt new file mode 100644 index 000000000..0b331e8c7 --- /dev/null +++ b/src/machine_table.txt @@ -0,0 +1,3 @@ +Comparing files MACHINE\machine_table.c and MACHINE\MACHINE_TABLE_NEW.C +FC: no differences encountered + diff --git a/src/mbuf.d b/src/mbuf.d new file mode 100644 index 000000000..0adbe97c0 --- /dev/null +++ b/src/mbuf.d @@ -0,0 +1,8 @@ +mbuf.o: network/slirp/mbuf.c network/slirp/slirp.h network/slirp/config.h \ + network/slirp/config-host.h network/slirp/slirp_config.h \ + network/slirp/debug.h network/slirp/ip.h network/slirp/tcp.h \ + network/slirp/tcp_var.h network/slirp/tcpip.h network/slirp/tcp_timer.h \ + network/slirp/udp.h network/slirp/icmp_var.h network/slirp/mbuf.h \ + network/slirp/sbuf.h network/slirp/socket.h network/slirp/if.h \ + network/slirp/main.h network/slirp/misc.h network/slirp/ctl.h \ + network/slirp/bootp.h network/slirp/tftp.h network/slirp/libslirp.h diff --git a/src/mca.c b/src/mca.c index 73e227b8e..b9ab31487 100644 --- a/src/mca.c +++ b/src/mca.c @@ -2,7 +2,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "mca.h" diff --git a/src/mca.d b/src/mca.d new file mode 100644 index 000000000..e01cf0061 --- /dev/null +++ b/src/mca.d @@ -0,0 +1 @@ +mca.o: mca.c 86box_io.h mca.h diff --git a/src/mcr.d b/src/mcr.d new file mode 100644 index 000000000..b7ef8475b --- /dev/null +++ b/src/mcr.d @@ -0,0 +1 @@ +mcr.o: mcr.c 86box.h mem.h diff --git a/src/mem.c b/src/mem.c index 0741e18d5..5e01127c0 100644 --- a/src/mem.c +++ b/src/mem.c @@ -12,15 +12,15 @@ * the DYNAMIC_TABLES=1 enables this. Will eventually go * away, either way... * - * Version: @(#)mem.c 1.0.22 2019/12/02 + * Version: @(#)mem.c 1.0.23 2020/01/25 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -30,23 +30,27 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" -#include "cpu/x86_ops.h" -#include "cpu/x86.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" +#include "cpu.h" +#include "x86_ops.h" +#include "x86.h" +#include "machine.h" +#include "m_xt_xi8088.h" #include "config.h" -#include "io.h" +#include "86box_io.h" #include "mem.h" #include "rom.h" #ifdef USE_DYNAREC -# include "cpu/codegen.h" +# include "codegen_public.h" +#else +#ifdef USE_NEW_DYNAREC +# define PAGE_MASK_SHIFT 6 #else # define PAGE_MASK_INDEX_MASK 3 # define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_MASK 63 # define PAGE_MASK_SHIFT 4 #endif +# define PAGE_MASK_MASK 63 +#endif #define FIXME 0 @@ -105,12 +109,18 @@ int mem_a20_key = 0, int mmuflush = 0; int mmu_perm = 4; +uint64_t *byte_dirty_mask; +uint64_t *byte_code_present_mask; + +uint32_t purgable_page_list_head = 0; +int purgeable_page_count = 0; + /* FIXME: re-do this with a 'mem_ops' struct. */ static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static int _mem_state[MEM_MAPPINGS_NO]; +static int _mem_state[MEM_MAPPINGS_NO], _mem_state_bak[MEM_MAPPINGS_NO]; #if FIXME #if (MEM_GRANULARITY_BITS >= 12) @@ -433,13 +443,17 @@ addwritelookup(uint32_t virt, uint32_t phys) writelookup2[writelookup[writelnext]] = -1; } +#ifdef USE_NEW_DYNAREC + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) +#else #ifdef USE_DYNAREC if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) #else if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) +#endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - else + else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; writelookupp[writelnext] = mmu_perm; @@ -512,16 +526,15 @@ writemembl(uint32_t addr, uint8_t val) mem_mapping_t *map; mem_logical_addr = addr; - if (page_lookup[addr>>12]) - { + if (page_lookup[addr>>12]) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; } if (cr0 >> 31) { addr = mmutranslate_write(addr); - if (addr == 0xffffffff) return; + if (addr == 0xffffffff) + return; } addr &= rammask; @@ -530,6 +543,297 @@ writemembl(uint32_t addr, uint8_t val) map->write_b(addr, val, map->p); } + +#ifdef USE_NEW_DYNAREC +uint16_t +readmemwl(uint32_t addr) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr+1) == 0xffffffff) + return 0xffff; + } + return readmembl(addr)|(readmembl(addr+1)<<8); + } else if (readlookup2[addr >> 12] != -1) + return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr == 0xffffffff) + return 0xffff; + } + + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map && map->read_w) + return map->read_w(addr, map->p); + + if (map && map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + + return 0xffff; +} + + +void +writememwl(uint32_t addr, uint16_t val) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+1) == 0xffffffff) + return; + } + writemembl(addr,val); + writemembl(addr+1,val>>8); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); + return; + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } + + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_w) + map->write_w(addr, val, map->p); + else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + } + } +} + + +uint32_t +readmemll(uint32_t addr) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr&0xFFF)>0xFFC) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+3) == 0xffffffff) + return 0xffffffff; + } + return readmemwl(addr)|(readmemwl(addr+2)<<16); + } else if (readlookup2[addr >> 12] != -1) + return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->read_l) + return map->read_l(addr, map->p); + + if (map->read_w) + return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | + (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); + } + + return 0xffffffff; +} + + +void +writememll(uint32_t addr, uint32_t val) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFC) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+3) == 0xffffffff) + return; + } + writememwl(addr,val); + writememwl(addr+2,val>>16); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + return; + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) + map->write_l(addr, val, map->p); + else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + } + } +} + + +uint64_t +readmemql(uint32_t addr) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+7) == 0xffffffff) + return 0xffffffff; + } + return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); + } else if (readlookup2[addr >> 12] != -1) + return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); + + return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); +} + + +void +writememql(uint32_t addr, uint64_t val) +{ + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+7) == 0xffffffff) + return; + } + writememll(addr, val); + writememll(addr+4, val >> 32); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); + return; + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) { + map->write_l(addr, val, map->p); + map->write_l(addr + 4, val >> 32, map->p); + } else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr + 4, val >> 32, map->p); + map->write_w(addr + 6, val >> 48, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr + 4, val >> 32, map->p); + map->write_b(addr + 5, val >> 40, map->p); + map->write_b(addr + 6, val >> 48, map->p); + map->write_b(addr + 7, val >> 56, map->p); + } + } +} +#else uint8_t readmemb386l(uint32_t seg, uint32_t addr) { @@ -553,10 +857,12 @@ readmemwl(uint32_t seg, uint32_t addr) if (addr2 & 1) { if (!cpu_cyrix_alignment || (addr2 & 7) == 7) sub_cycles(timing_misaligned); - if ((addr2 & 0xFFF) > 0xffe) { + if ((addr2 & 0xfff) > 0xffe) { if (cr0 >> 31) { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; - if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) + return 0xffff; } if (is386) return readmemb386l(seg,addr)|(((uint16_t) readmemb386l(seg,addr+1))<<8); else return readmembl(seg+addr)|(((uint16_t) readmembl(seg+addr+1))<<8); @@ -568,7 +874,7 @@ readmemwl(uint32_t seg, uint32_t addr) if (cr0 >> 31) { addr2 = mmutranslate_read(addr2); if (addr2 == 0xffffffff) - return 0xFFFF; + return 0xffff; } addr2 &= rammask; @@ -843,6 +1149,7 @@ writememql(uint32_t seg, uint32_t addr, uint64_t val) return; } } +#endif int @@ -894,6 +1201,7 @@ mem_readw_phys(uint32_t addr) return temp; } + uint32_t mem_readl_phys(uint32_t addr) { @@ -914,6 +1222,7 @@ mem_readl_phys(uint32_t addr) return temp; } + void mem_writeb_phys(uint32_t addr, uint8_t val) { @@ -925,6 +1234,7 @@ mem_writeb_phys(uint32_t addr, uint8_t val) map->write_b(addr, val, map->p); } + void mem_writel_phys(uint32_t addr, uint32_t val) { @@ -943,6 +1253,7 @@ mem_writel_phys(uint32_t addr, uint32_t val) } } + uint8_t mem_read_ram(uint32_t addr, void *priv) { @@ -970,6 +1281,114 @@ mem_read_raml(uint32_t addr, void *priv) } +#ifdef USE_NEW_DYNAREC +static inline int +page_index(page_t *p) +{ + return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); +} + + +void +page_add_to_evict_list(page_t *p) +{ + pages[purgable_page_list_head].evict_prev = page_index(p); + p->evict_next = purgable_page_list_head; + p->evict_prev = 0; + purgable_page_list_head = pages[purgable_page_list_head].evict_prev; + purgeable_page_count++; +} + + +void +page_remove_from_evict_list(page_t *p) +{ + if (!page_in_evict_list(p)) + fatal("page_remove_from_evict_list: not in evict list!\n"); + if (p->evict_prev) + pages[p->evict_prev].evict_next = p->evict_next; + else + purgable_page_list_head = p->evict_next; + if (p->evict_next) + pages[p->evict_next].evict_prev = p->evict_prev; + p->evict_prev = EVICT_NOT_IN_LIST; + purgeable_page_count--; +} + + +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + p->byte_dirty_mask[byte_offset] |= byte_mask; + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} + + +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + *(uint16_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { + p->byte_dirty_mask[byte_offset+1] |= 1; + if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } else + byte_mask |= (byte_mask << 1); + + p->byte_dirty_mask[byte_offset] |= byte_mask; + + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} + + +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + *(uint32_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) { + uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); + + p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; + if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } + } +} +#else void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { @@ -1017,6 +1436,7 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) *(uint32_t *)&p->mem[addr & 0xfff] = val; } } +#endif void @@ -1169,12 +1589,32 @@ mem_write_nulll(uint32_t addr, uint32_t val, void *p) void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) { + uint64_t mask; +#ifdef USE_NEW_DYNAREC + page_t *p; + + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + if ((start_addr >> 12) >= pages_sz) + continue; + + mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + p = &pages[start_addr >> 12]; + + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +#else uint32_t cur_addr; start_addr &= ~PAGE_MASK_MASK; end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { - uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); /* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses may crash the emulator. */ @@ -1182,6 +1622,7 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) if (cur_addr < pages_sz) pages[cur_addr].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; } +#endif } @@ -1278,11 +1719,11 @@ mem_mapping_recalc(uint64_t base, uint64_t size) for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { if ((map->read_b || map->read_w || map->read_l) && mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { + read_mapping[c >> MEM_GRANULARITY_BITS] = map; if (map->exec) _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); else _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - read_mapping[c >> MEM_GRANULARITY_BITS] = map; } if ((map->write_b || map->write_w || map->write_l) && mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) @@ -1440,8 +1881,22 @@ mem_set_mem_state(uint32_t base, uint32_t size, int state) { uint32_t c; - for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS]; _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; + } + + mem_mapping_recalc(base, size); +} + + +void +mem_restore_mem_state(uint32_t base, uint32_t size) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS]; mem_mapping_recalc(base, size); } @@ -1572,12 +2027,32 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); memset(pages, 0x00, pages_sz*sizeof(page_t)); +#ifdef USE_NEW_DYNAREC + if (byte_dirty_mask) { + free(byte_dirty_mask); + byte_dirty_mask = NULL; + } + byte_dirty_mask = malloc((mem_size * 1024) / 8); + memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); + + if (byte_code_present_mask) { + free(byte_code_present_mask); + byte_code_present_mask = NULL; + } + byte_code_present_mask = malloc((mem_size * 1024) / 8); + memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); +#endif for (c = 0; c < pages_sz; c++) { pages[c].mem = &ram[c << 12]; pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; +#endif } memset(_mem_exec, 0x00, sizeof(_mem_exec)); @@ -1585,6 +2060,7 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); memset(&base_mapping, 0x00, sizeof(base_mapping)); memset(_mem_state, 0x00, sizeof(_mem_state)); + memset(_mem_state_bak, 0x00, sizeof(_mem_state_bak)); mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); @@ -1630,6 +2106,11 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); mem_mapping_disable(&ram_remapped_mapping); mem_a20_init(); + +#ifdef USE_NEW_DYNAREC + purgable_page_list_head = 0; + purgeable_page_count = 0; +#endif } @@ -1667,7 +2148,7 @@ mem_remap_top(int kb) { int c; uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int size = mem_size - 640; + int offset, size = mem_size - 640; mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); if (mem_size <= 640) return; @@ -1683,10 +2164,16 @@ mem_remap_top(int kb) size = kb; for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - pages[c].mem = &ram[0xA0000 + ((c - ((start * 1024) >> 12)) << 12)]; + offset = c - ((start * 1024) >> 12); + pages[c].mem = &ram[0xA0000 + (offset << 12)]; pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; +#ifdef USE_NEW_DYNAREC + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; +#endif } mem_set_mem_state(start * 1024, size * 1024, @@ -1697,6 +2184,7 @@ mem_remap_top(int kb) flushmmucache(); } + void mem_reset_page_blocks(void) { @@ -1708,8 +2196,13 @@ mem_reset_page_blocks(void) pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; +#ifdef USE_NEW_DYNAREC + pages[c].block = BLOCK_INVALID; + pages[c].block_2 = BLOCK_INVALID; +#else pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; +#endif } } diff --git a/src/mem.d b/src/mem.d new file mode 100644 index 000000000..10ac5a600 --- /dev/null +++ b/src/mem.d @@ -0,0 +1,4 @@ +mem.o: mem.c 86box.h cpu_common/cpu.h cpu_common/x86_ops.h \ + cpu_common/x86.h machine/machine.h machine/m_xt_xi8088.h \ + machine/../device.h config.h 86box_io.h mem.h rom.h \ + cpu_common/codegen_public.h diff --git a/src/mem.h b/src/mem.h index 6b5641ee6..badcb2d3c 100644 --- a/src/mem.h +++ b/src/mem.h @@ -8,15 +8,15 @@ * * Definitions for the memory interface. * - * Version: @(#)mem.h 1.0.10 2019/10/19 + * Version: @(#)mem.h 1.0.11 2020/01/25 * * Authors: Sarah Walker, * Fred N. van Kempen, * Miran Grca, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. */ #ifndef EMU_MEM_H # define EMU_MEM_H @@ -262,6 +262,7 @@ extern void mem_mapping_disable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *); extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); +extern void mem_restore_mem_state(uint32_t base, uint32_t size); extern uint8_t mem_readb_phys(uint32_t addr); extern uint16_t mem_readw_phys(uint32_t addr); @@ -302,6 +303,7 @@ extern void flushmmucache_cr3(void); extern void flushmmucache_nopc(void); extern void mmu_invalidate(uint32_t addr); +extern void mem_a20_init(void); extern void mem_a20_recalc(void); extern void mem_add_upper_bios(void); diff --git a/src/mem.txt b/src/mem.txt new file mode 100644 index 000000000..e0b8dbede --- /dev/null +++ b/src/mem.txt @@ -0,0 +1,2466 @@ +Comparing files mem.c and MEM_NEW.C +***** mem.c + + +***** MEM_NEW.C + +uint64_t *byte_dirty_mask; +uint64_t *byte_code_present_mask; + +uint32_t purgable_page_list_head = 0; +int purgeable_page_count = 0; + + +***** + +***** mem.c + +#ifdef USE_DYNAREC + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || + (phys & ~0xfff) == recomp_page) +#else + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) +#endif + page_lookup[virt >> 12] = &pages[phys >> 12]; + else + writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; +***** MEM_NEW.C + + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) + page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)] +; + else + writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; +***** + +***** mem.c + page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); + + return; +***** MEM_NEW.C + page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); + return; +***** + +***** mem.c + addr = mmutranslate_write(addr); + if (addr == 0xffffffff) + return; +***** MEM_NEW.C + addr = mmutranslate_write(addr); + if (addr == 0xFFFFFFFF) + return; +***** + +***** mem.c + if (map && map->write_b) + map->write_b(addr, val, map->p); +} +***** MEM_NEW.C + if (map && map->write_b) + return map->write_b(addr, val, map->p); +} +***** + +***** mem.c + +uint8_t +readmemb386l(uint32_t seg, uint32_t addr) +{ + return readmembl(addr + seg); +} + + +void +writememb386l(uint32_t seg, uint32_t addr, uint8_t val) +{ + writemembl(addr + seg, val); +} + + +***** MEM_NEW.C + + +***** + +***** mem.c +uint16_t +readmemwl(uint32_t seg, uint32_t addr) +{ +***** MEM_NEW.C +uint16_t +readmemwl(uint32_t addr) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 1) { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr2 & 0xFFF) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + } + if (is386) return readmemb386l(seg,addr)|(((uint16_t) readmemb386l(seg,addr+1))<<8); + else return readmembl(seg+addr)|(((uint16_t) readmembl(seg+addr+1))<<8); + } + else if (readlookup2[addr2 >> 12] != (uintptr_t) -1) + return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); + } + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return 0xFFFF; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr+1) == 0xffffffff) + return 0xffff; + } + return readmembl(addr)|(readmembl(addr+1)<<8); + } else if (readlookup2[addr >> 12] != -1) + return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFF; +***** + +***** mem.c + + addr2 &= rammask; + + map = read_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->read_w) + return map->read_w(addr2, map->p); + + if (map && map->read_b) { + if (AT) + return map->read_b(addr2, map->p) | + ((uint16_t) (map->read_b(addr2 + 1, map->p)) << 8); + else + return map->read_b(addr2, map->p) | + ((uint16_t) (map->read_b(seg + ((addr + 1) & 0xffff), map->p)) << 8); + } +***** MEM_NEW.C + + addr &= rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->read_w) + return map->read_w(addr, map->p); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + } +***** + +***** mem.c +void +writememwl(uint32_t seg, uint32_t addr, uint16_t val) +{ +***** MEM_NEW.C +void +writememwl(uint32_t addr, uint16_t val) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 1) { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr2 & 0xFFF) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+1) == 0xffffffff) return; + } + if (is386) { + writememb386l(seg,addr,val); + writememb386l(seg,addr+1,val>>8); + } else { + writemembl(seg+addr,val); + writemembl(seg+addr+1,val>>8); + } + return; + } else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) { + *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+1) == 0xffffffff) + return; + } + writemembl(addr,val); + writemembl(addr+1,val>>8); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; + return; +***** + +***** mem.c + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); + return; +***** MEM_NEW.C + + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); + return; +***** + +***** mem.c + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } +***** MEM_NEW.C + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = write_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->write_w) { + map->write_w(addr2, val, map->p); + return; + } + + if (map && map->write_b) { + map->write_b(addr2, val, map->p); + map->write_b(addr2 + 1, val >> 8, map->p); + return; + } +***** MEM_NEW.C + + addr &= rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_w) + map->write_w(addr, val, map->p); + else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + } + } +***** + +***** mem.c +uint32_t +readmemll(uint32_t seg, uint32_t addr) +{ +***** MEM_NEW.C +uint32_t +readmemll(uint32_t addr) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 3) { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; + } + return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + } else if (readlookup2[addr2 >> 12] != (uintptr_t) -1) + return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); + } +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr&0xFFF)>0xFFC) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+3) == 0xffffffff) + return 0xffffffff; + } + return readmemwl(addr)|(readmemwl(addr+2)<<16); + } else if (readlookup2[addr >> 12] != -1) + return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } +***** + +***** mem.c + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return 0xffffffff; + } +***** MEM_NEW.C + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = read_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->read_l) + return map->read_l(addr2, map->p); + + if (map && map->read_w) + return map->read_w(addr2, map->p) | + ((uint32_t) (map->read_w(addr2 + 2, map->p)) << 16); + + if (map && map->read_b) + return map->read_b(addr2, map->p) | + ((uint32_t) (map->read_b(addr2 + 1, map->p)) << 8) | + ((uint32_t) (map->read_b(addr2 + 2, map->p)) << 16) | + ((uint32_t) (map->read_b(addr2 + 3, map->p)) << 24); + +***** MEM_NEW.C + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->read_l) + return map->read_l(addr, map->p); + + if (map->read_w) + return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | + (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); + } + +***** + +***** mem.c +void +writememll(uint32_t seg, uint32_t addr, uint32_t val) +{ +***** MEM_NEW.C +void +writememll(uint32_t addr, uint32_t val) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 3) { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+3) == 0xffffffff) return; + } + writememwl(seg,addr,val); + writememwl(seg,addr+2,val>>16); + return; + } else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) { + *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFFC) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+3) == 0xffffffff) + return; + } + writememwl(addr,val); + writememwl(addr+2,val>>16); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; + return; +***** + +***** mem.c + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + return; +***** MEM_NEW.C + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + return; +***** + +***** mem.c + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } +***** MEM_NEW.C + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = write_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr2, val, map->p); + return; + } + if (map && map->write_w) { + map->write_w(addr2, val, map->p); + map->write_w(addr2 + 2, val >> 16, map->p); + return; + } + if (map && map->write_b) { + map->write_b(addr2, val, map->p); + map->write_b(addr2 + 1, val >> 8, map->p); + map->write_b(addr2 + 2, val >> 16, map->p); + map->write_b(addr2 + 3, val >> 24, map->p); + return; + } +***** MEM_NEW.C + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) + map->write_l(addr, val, map->p); + else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + } + } +***** + +***** mem.c +uint64_t +readmemql(uint32_t seg, uint32_t addr) +{ +***** MEM_NEW.C +uint64_t +readmemql(uint32_t addr) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 7) { + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xff8) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + } + return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + } else if (readlookup2[addr2 >> 12] != (uintptr_t) -1) + return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); + } +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr+7) == 0xffffffff) + return 0xffffffff; + } + return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); + } else if (readlookup2[addr >> 12] != -1) + return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } +***** + +***** mem.c + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return -1; + } +***** MEM_NEW.C + + if (cr0>>31) { + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) + return 0xFFFFFFFF; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = read_mapping[addr2 >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr2, map->p) | ((uint64_t)map->read_l(addr2 + 4, map->p) << 32); + + return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); +} +***** MEM_NEW.C + + addr&=rammask; + + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map && map->read_l) + return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); + + return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); +} +***** + +***** mem.c +void +writememql(uint32_t seg, uint32_t addr, uint64_t val) +{ +***** MEM_NEW.C +void +writememql(uint32_t addr, uint64_t val) +{ +***** + +***** mem.c + mem_mapping_t *map; + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (addr2 & 7) { + sub_cycles(timing_misaligned); + if ((addr2 & 0xfff) > 0xff8) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+7) == 0xffffffff) return; + } + writememll(seg, addr, val); + writememll(seg, addr+4, val >> 32); + return; + } else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) { + *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; +***** MEM_NEW.C + mem_mapping_t *map; + + mem_logical_addr = addr; + + if (addr & 7) { + sub_cycles(timing_misaligned); + if ((addr & 0xFFF) > 0xFF8) { + if (cr0>>31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr+7) == 0xffffffff) + return; + } + writememll(addr, val); + writememll(addr+4, val >> 32); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; + return; +***** + +***** mem.c + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]); + return; +***** MEM_NEW.C + } + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); + return; +***** + +***** mem.c + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } +***** MEM_NEW.C + } + if (cr0>>31) { + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) + return; + } +***** + +***** mem.c + + addr2 &= rammask; + + map = write_mapping[addr2 >> MEM_GRANULARITY_BITS]; + + if (map && map->write_l) { + map->write_l(addr2, val, map->p); + map->write_l(addr2+4, val >> 32, map->p); + return; + } + if (map && map->write_w) { + map->write_w(addr2, val, map->p); + map->write_w(addr2 + 2, val >> 16, map->p); + map->write_w(addr2 + 4, val >> 32, map->p); + map->write_w(addr2 + 6, val >> 48, map->p); + return; + } + if (map && map->write_b) { + map->write_b(addr2, val, map->p); + map->write_b(addr2 + 1, val >> 8, map->p); + map->write_b(addr2 + 2, val >> 16, map->p); + map->write_b(addr2 + 3, val >> 24, map->p); + map->write_b(addr2 + 4, val >> 32, map->p); + map->write_b(addr2 + 5, val >> 40, map->p); + map->write_b(addr2 + 6, val >> 48, map->p); + map->write_b(addr2 + 7, val >> 56, map->p); + return; + } +***** MEM_NEW.C + + addr&=rammask; + + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + if (map) { + if (map->write_l) { + map->write_l(addr, val, map->p); + map->write_l(addr + 4, val >> 32, map->p); + } else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr + 4, val >> 32, map->p); + map->write_w(addr + 6, val >> 48, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr + 4, val >> 32, map->p); + map->write_b(addr + 5, val >> 40, map->p); + map->write_b(addr + 6, val >> 48, map->p); + map->write_b(addr + 7, val >> 56, map->p); + } + } +***** + +***** mem.c + +void +***** MEM_NEW.C + + +void +***** + +***** mem.c + +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + p->mem[addr & 0xfff] = val; + } +} +***** MEM_NEW.C + +static inline int +page_index(page_t *p) +{ + return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); +} +***** + +***** mem.c +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint16_t *)&p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint16_t *)&p->mem[addr & 0xfff] = val; + } +} +***** MEM_NEW.C +void +page_add_to_evict_list(page_t *p) +{ + pages[purgable_page_list_head].evict_prev = page_index(p); + p->evict_next = purgable_page_list_head; + p->evict_prev = 0; + purgable_page_list_head = pages[purgable_page_list_head].evict_prev; + purgeable_page_count++; +} +***** + +***** mem.c +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint32_t *)&p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint32_t *)&p->mem[addr & 0xfff] = val; + } +} +***** MEM_NEW.C +void +page_remove_from_evict_list(page_t *p) +{ + if (!page_in_evict_list(p)) + fatal("page_remove_from_evict_list: not in evict list!\n"); + if (p->evict_prev) + pages[p->evict_prev].evict_next = p->evict_next; + else + purgable_page_list_head = p->evict_next; + if (p->evict_next) + pages[p->evict_next].evict_prev = p->evict_prev; + p->evict_prev = EVICT_NOT_IN_LIST; + purgeable_page_count--; +} +***** + +***** mem.c +void +mem_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[addr >> 12]); +} +***** MEM_NEW.C +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + p->byte_dirty_mask[byte_offset] |= byte_mask; + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} +***** + +***** mem.c +void +mem_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[addr >> 12]); +} +***** MEM_NEW.C +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + *(uint16_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { + p->byte_dirty_mask[byte_offset+1] |= 1; + if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } else + byte_mask |= (byte_mask << 1); + + p->byte_dirty_mask[byte_offset] |= byte_mask; + + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} +***** + +***** mem.c +void +mem_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); +} +***** MEM_NEW.C +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); + + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + *(uint32_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) + page_add_to_evict_list(p); + if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) { + uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); + + p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; + if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } + } +} +***** + +***** mem.c + +static uint8_t +mem_read_remapped(uint32_t addr, void *priv) +{ + if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; +} +***** MEM_NEW.C + +void +mem_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[addr >> 12]); +} +***** + +***** mem.c + +static uint16_t +mem_read_remappedw(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; +} +***** MEM_NEW.C + +void +mem_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[addr >> 12]); +} +***** + +***** mem.c + +static uint32_t +mem_read_remappedl(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; +} +***** MEM_NEW.C + +void +mem_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); +} +***** + +***** mem.c + +static void +mem_write_remapped(uint32_t addr, uint8_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); +} +***** MEM_NEW.C + +static uint8_t +mem_read_remapped(uint32_t addr, void *priv) +{ + if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; +} +***** + +***** mem.c + +static void +mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** MEM_NEW.C + +static uint16_t +mem_read_remappedw(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** + +***** mem.c + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); +} +***** MEM_NEW.C + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; +} +***** + +***** mem.c + +static void +mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** MEM_NEW.C + +static uint32_t +mem_read_remappedl(uint32_t addr, void *priv) +{ + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) +***** + +***** mem.c + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); +} +***** MEM_NEW.C + addr = 0xA0000 + (addr - (mem_size * 1024)); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; +} +***** + +***** mem.c + +uint8_t +mem_read_bios(uint32_t addr, void *priv) +{ + uint8_t ret = 0xff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = rom[addr - biosaddr]; + + return ret; +} +***** MEM_NEW.C + +static void +mem_write_remapped(uint32_t addr, uint8_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); +} +***** + +***** mem.c + +uint16_t +mem_read_biosw(uint32_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint16_t *)&rom[addr - biosaddr]; + + return ret; +} +***** MEM_NEW.C + +static void +mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); +} +***** + +***** mem.c + +uint32_t +mem_read_biosl(uint32_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint32_t *)&rom[addr - biosaddr]; + + return ret; +} +***** MEM_NEW.C + +static void +mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) +{ + uint32_t oldaddr = addr; + if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) + addr = 0xA0000 + (addr - (mem_size * 1024)); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); +} +***** + +***** mem.c + +void +mem_write_null(uint32_t addr, uint8_t val, void *p) +{ +} +***** MEM_NEW.C + +uint8_t +mem_read_bios(uint32_t addr, void *priv) +{ + uint8_t ret = 0xff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = rom[addr - biosaddr]; + + return ret; +} +***** + +***** mem.c + +void +mem_write_nullw(uint32_t addr, uint16_t val, void *p) +{ +} +***** MEM_NEW.C + +uint16_t +mem_read_biosw(uint32_t addr, void *priv) +{ + uint16_t ret = 0xffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint16_t *)&rom[addr - biosaddr]; + + return ret; +} +***** + +***** mem.c + +void +mem_write_nulll(uint32_t addr, uint32_t val, void *p) +{ +} +***** MEM_NEW.C + +uint32_t +mem_read_biosl(uint32_t addr, void *priv) +{ + uint32_t ret = 0xffffffff; + + addr &= 0x000fffff; + + if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) + ret = *(uint32_t *)&rom[addr - biosaddr]; + + return ret; +} +***** + +***** mem.c +void +mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) +{ + uint32_t cur_addr; + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + /* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses + may crash the emulator. */ + cur_addr = (start_addr >> 12); + if (cur_addr < pages_sz) + pages[cur_addr].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + } +} +***** MEM_NEW.C +void +mem_write_null(uint32_t addr, uint8_t val, void *p) +{ +} +***** + +***** mem.c + +static __inline int +mem_mapping_read_allowed(uint32_t flags, int state) +{ + switch (state & MEM_READ_MASK) { + case MEM_READ_DISABLED: + return 0; + + case MEM_READ_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_READ_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_READ_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_READ_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_READ_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_read_allowed : bad state %x\n", state); + } + + return 0; +} +***** MEM_NEW.C + +void +mem_write_nullw(uint32_t addr, uint16_t val, void *p) +{ +} +***** + +***** mem.c + +static __inline int +mem_mapping_write_allowed(uint32_t flags, int state) +{ + switch (state & MEM_WRITE_MASK) { + case MEM_WRITE_DISABLED: + return 0; + + case MEM_WRITE_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_WRITE_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_WRITE_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_WRITE_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_WRITE_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_write_allowed : bad state %x\n", state); + } + + return 0; +} +***** MEM_NEW.C + +void +mem_write_nulll(uint32_t addr, uint32_t val, void *p) +{ +} +***** + +***** mem.c + +static void +mem_mapping_recalc(uint64_t base, uint64_t size) +{ + mem_mapping_t *map = base_mapping.next; + uint64_t c; + + if (! size) return; + + /* Clear out old mappings. */ + for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { + read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + } + + /* Walk mapping list. */ + while (map != NULL) { + /*In range?*/ + if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->siz +e) > (uint64_t)base) { + uint64_t start = (map->base < base) ? map->base : base; + uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64 +_t)map->size) : (base + size); + if (start < map->base) + start = map->base; + + for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { + if (map->exec) + _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); + else + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + read_mapping[c >> MEM_GRANULARITY_BITS] = map; + } + if ((map->write_b || map->write_w || map->write_l) && + mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) + write_mapping[c >> MEM_GRANULARITY_BITS] = map; + } + } + map = map->next; + } + + flushmmucache_cr3(); +} +***** MEM_NEW.C + +void +mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) +{ + uint64_t mask; + page_t *p; + + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + if ((start_addr >> 12) >= pages_sz) + continue; + + mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + p = &pages[start_addr >> 12]; + + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + } +} +***** + +***** mem.c + +void +mem_mapping_del(mem_mapping_t *map) +{ + mem_mapping_t *ptr; + + /* Disable the entry. */ + mem_mapping_disable(map); + + /* Zap it from the list. */ + for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) { + if (ptr->next == map) { + ptr->next = map->next; + break; + } + } +} +***** MEM_NEW.C + +static __inline int +mem_mapping_read_allowed(uint32_t flags, int state) +{ + switch (state & MEM_READ_MASK) { + case MEM_READ_DISABLED: + return 0; + + case MEM_READ_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_READ_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_READ_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_READ_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_READ_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_read_allowed : bad state %x\n", state); + } + + return 0; +} +***** + +***** mem.c + +void +mem_mapping_add(mem_mapping_t *map, + uint32_t base, + uint32_t size, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t fl, + void *p) +{ + mem_mapping_t *dest = &base_mapping; + + /* Add mapping to the end of the list.*/ + while (dest->next) + dest = dest->next; + dest->next = map; + map->prev = dest; + + if (size) + map->enable = 1; + else + map->enable = 0; + map->base = base; + map->size = size; + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + map->exec = exec; + map->flags = fl; + map->p = p; + map->dev = NULL; + map->next = NULL; + + mem_mapping_recalc(map->base, map->size); +} +***** MEM_NEW.C + +static __inline int +mem_mapping_write_allowed(uint32_t flags, int state) +{ + switch (state & MEM_WRITE_MASK) { + case MEM_WRITE_DISABLED: + return 0; + + case MEM_WRITE_ANY: + return 1; + + /* On external and 0 mappings without ROMCS. */ + case MEM_WRITE_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + + /* On external and 0 mappings with ROMCS. */ + case MEM_WRITE_ROMCS: + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + + /* On any external mappings. */ + case MEM_WRITE_EXTANY: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_WRITE_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_write_allowed : bad state %x\n", state); + } + + return 0; +} +***** + +***** mem.c + +void +mem_mapping_set_handler(mem_mapping_t *map, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p)) +{ + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + + mem_mapping_recalc(map->base, map->size); +} +***** MEM_NEW.C + +static void +mem_mapping_recalc(uint64_t base, uint64_t size) +{ + mem_mapping_t *map = base_mapping.next; + uint64_t c; + + if (! size) return; + + /* Clear out old mappings. */ + for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { + read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + } + + /* Walk mapping list. */ + while (map != NULL) { + /*In range?*/ + if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->siz +e) > (uint64_t)base) { + uint64_t start = (map->base < base) ? map->base : base; + uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64 +_t)map->size) : (base + size); + if (start < map->base) + start = map->base; + + for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { + read_mapping[c >> MEM_GRANULARITY_BITS] = map; + if (map->exec) + _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); + else + _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; + } + if ((map->write_b || map->write_w || map->write_l) && + mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) + write_mapping[c >> MEM_GRANULARITY_BITS] = map; + } + } + map = map->next; + } + + flushmmucache_cr3(); +} +***** + +***** mem.c +void +mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) +{ + /* Remove old mapping. */ + map->enable = 0; + mem_mapping_recalc(map->base, map->size); + + /* Set new mapping. */ + map->enable = 1; + map->base = base; + map->size = size; + + mem_mapping_recalc(map->base, map->size); +} +***** MEM_NEW.C +void +mem_mapping_del(mem_mapping_t *map) +{ + mem_mapping_t *ptr; + + /* Disable the entry. */ + mem_mapping_disable(map); + + /* Zap it from the list. */ + for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) { + if (ptr->next == map) { + ptr->next = map->next; + break; + } + } +} +***** + +***** mem.c +void +mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) +{ + map->exec = exec; + +***** MEM_NEW.C +void +mem_mapping_add(mem_mapping_t *map, + uint32_t base, + uint32_t size, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t fl, + void *p) +{ + mem_mapping_t *dest = &base_mapping; + + /* Add mapping to the end of the list.*/ + while (dest->next) + dest = dest->next; + dest->next = map; + map->prev = dest; + + if (size) + map->enable = 1; + else + map->enable = 0; + map->base = base; + map->size = size; + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + map->exec = exec; + map->flags = fl; + map->p = p; + map->dev = NULL; + map->next = NULL; + +***** + +***** mem.c +void +mem_mapping_set_p(mem_mapping_t *map, void *p) +{ + map->p = p; +} +***** MEM_NEW.C +void +mem_mapping_set_handler(mem_mapping_t *map, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p)) +{ + map->read_b = read_b; + map->read_w = read_w; + map->read_l = read_l; + map->write_b = write_b; + map->write_w = write_w; + map->write_l = write_l; + + mem_mapping_recalc(map->base, map->size); +} +***** + +***** mem.c +void +mem_mapping_set_dev(mem_mapping_t *map, void *p) +{ + map->dev = p; +} + + +void +mem_mapping_disable(mem_mapping_t *map) +{ + map->enable = 0; + +***** MEM_NEW.C +void +mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) +{ + /* Remove old mapping. */ + map->enable = 0; + mem_mapping_recalc(map->base, map->size); + + /* Set new mapping. */ + map->enable = 1; + map->base = base; + map->size = size; + +***** + +***** mem.c +void +mem_mapping_enable(mem_mapping_t *map) +{ + map->enable = 1; + +***** MEM_NEW.C +void +mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) +{ + map->exec = exec; + +***** + +***** mem.c +void +mem_set_mem_state(uint32_t base, uint32_t size, int state) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS]; + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; + } + + mem_mapping_recalc(base, size); +} +***** MEM_NEW.C +void +mem_mapping_set_p(mem_mapping_t *map, void *p) +{ + map->p = p; +} +***** + +***** mem.c +void +mem_restore_mem_state(uint32_t base, uint32_t size) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS]; + + mem_mapping_recalc(base, size); +} +***** MEM_NEW.C +void +mem_mapping_set_dev(mem_mapping_t *map, void *p) +{ + map->dev = p; +} +***** + +***** mem.c +void +mem_add_bios(void) +{ + if (biosmask > 0x1ffff) { + /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ + mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(0x0e0000, 0x20000, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } else { + mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr, biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +***** MEM_NEW.C +void +mem_mapping_disable(mem_mapping_t *map) +{ + map->enable = 0; + + mem_mapping_recalc(map->base, map->size); +} + + +void +mem_mapping_enable(mem_mapping_t *map) +{ + map->enable = 1; + + mem_mapping_recalc(map->base, map->size); +} + + +void +mem_set_mem_state(uint32_t base, uint32_t size, int state) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS]; + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; + } +***** + +***** mem.c + + if (AT) { + mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +} +***** MEM_NEW.C + + mem_mapping_recalc(base, size); +} +***** + +***** mem.c +void +mem_a20_init(void) +{ + if (AT) { + rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; + flushmmucache(); + mem_a20_state = mem_a20_key | mem_a20_alt; + } else { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + } +} +***** MEM_NEW.C +void +mem_restore_mem_state(uint32_t base, uint32_t size) +{ + uint32_t c; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS]; + + mem_mapping_recalc(base, size); +} +***** + +***** mem.c + +/* Reset the memory state. */ +void +mem_reset(void) +{ + uint32_t c, m; + + m = 1024UL * mem_size; + if (ram != NULL) { + free(ram); + ram = NULL; + } + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + + /* + * Allocate the page table based on how much RAM we have. + * We re-allocate the table on each (hard) reset, as the + * memory amount could have changed. + */ + if (AT) { + if (cpu_16bitbus) { + /* 80186/286; maximum address space is 16MB. */ + m = 4096; + } else { + /* 80386+; maximum address space is 4GB. */ + m = (mem_size + 384) >> 2; + if ((m << 2) < (mem_size + 384)) + m++; + if (m < 4096) + m = 4096; + } + } else { + /* 8088/86; maximum address space is 1MB. */ + m = 256; + } +***** MEM_NEW.C + +void +mem_add_bios(void) +{ + if (biosmask > 0x1ffff) { + /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ + mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(0x0e0000, 0x20000, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } else { + mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr, biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +***** + +***** mem.c + + /* + * Allocate and initialize the (new) page table. + * We only do this if the size of the page table has changed. + */ +#if DYNAMIC_TABLES +mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + if (pages_sz != m) { + pages_sz = m; + if (pages) { + free(pages); + pages = NULL; + } + pages = (page_t *)malloc(m*sizeof(page_t)); +#if DYNAMIC_TABLES +mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + +#if DYNAMIC_TABLES + /* Allocate the (new) lookup tables. */ + if (page_lookup != NULL) free(page_lookup); + page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); + + if (readlookup2 != NULL) free(readlookup2); + readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); + + if (writelookup2 != NULL) free(writelookup2); + writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); + +#endif + } + +#if DYNAMIC_TABLES + memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); +#else + memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); +#endif + + memset(pages, 0x00, pages_sz*sizeof(page_t)); + +***** MEM_NEW.C + + if (AT) { + mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); + + mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } +} + +***** + +***** mem.c + + for (c = 0; c < pages_sz; c++) { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } +***** MEM_NEW.C + +void +mem_a20_init(void) +{ + if (AT) { + rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; + flushmmucache(); + mem_a20_state = mem_a20_key | mem_a20_alt; + } else { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + } +} + + +/* Reset the memory state. */ +void +mem_reset(void) +{ + uint32_t c, m; + + m = 1024UL * mem_size; + if (ram != NULL) { + free(ram); + ram = NULL; + } + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + + /* + * Allocate the page table based on how much RAM we have. + * We re-allocate the table on each (hard) reset, as the + * memory amount could have changed. + */ + if (AT) { + if (cpu_16bitbus) { + /* 80186/286; maximum address space is 16MB. */ + m = 4096; + } else { + /* 80386+; maximum address space is 4GB. */ + m = (mem_size + 384) >> 2; + if ((m << 2) < (mem_size + 384)) + m++; + if (m < 4096) + m = 4096; + } + } else { + /* 8088/86; maximum address space is 1MB. */ + m = 256; + } +***** + +***** mem.c + + memset(_mem_exec, 0x00, sizeof(_mem_exec)); + + memset(&base_mapping, 0x00, sizeof(base_mapping)); + + memset(_mem_state, 0x00, sizeof(_mem_state)); + memset(_mem_state_bak, 0x00, sizeof(_mem_state_bak)); + + mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x0c0000, 0x40000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, + (mem_size > 640) ? 0xa0000 : mem_size * 1024, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram, MEM_MAPPING_INTERNAL, NULL); + + if (mem_size > 1024) { + if (cpu_16bitbus && mem_size > 16256) { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((16256 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + } +***** MEM_NEW.C + + /* + * Allocate and initialize the (new) page table. + * We only do this if the size of the page table has changed. + */ +#if DYNAMIC_TABLES +mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + if (pages_sz != m) { + pages_sz = m; + if (pages) { + free(pages); + pages = NULL; + } + pages = (page_t *)malloc(m*sizeof(page_t)); +#if DYNAMIC_TABLES +mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + +#if DYNAMIC_TABLES + /* Allocate the (new) lookup tables. */ + if (page_lookup != NULL) free(page_lookup); + page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); + + if (readlookup2 != NULL) free(readlookup2); + readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); + + if (writelookup2 != NULL) free(writelookup2); + writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); + +#endif + } +***** + +***** mem.c + + if (mem_size > 768) + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); + + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, + mem_read_remapped,mem_read_remappedw,mem_read_remappedl, + mem_write_remapped,mem_write_remappedw,mem_write_remappedl, + ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ram_remapped_mapping); + + mem_a20_init(); +} + +***** MEM_NEW.C + +#if DYNAMIC_TABLES + memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); +#else + memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); +#endif + + memset(pages, 0x00, pages_sz*sizeof(page_t)); + +***** + +***** mem.c + +void +mem_init(void) +{ + /* Perform a one-time init. */ + ram = rom = NULL; + pages = NULL; +#if DYNAMIC_TABLES + page_lookup = NULL; + readlookup2 = NULL; + writelookup2 = NULL; + +#else + /* Allocate the lookup tables. */ + page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + + readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + + writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); +#endif + +#if FIXME + memset(ff_array, 0xff, sizeof(ff_array)); +#endif + + /* Reset the memory state. */ + mem_reset(); +} + + +void +mem_remap_top(int kb) +{ + int c; + uint32_t start = (mem_size >= 1024) ? mem_size : 1024; + int size = mem_size - 640; + + mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); + if (mem_size <= 640) return; + + if (kb == 0) { + /* Called to disable the mapping. */ + mem_mapping_disable(&ram_remapped_mapping); + + return; + } + + if (size > kb) + size = kb; + + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { + pages[c].mem = &ram[0xA0000 + ((c - ((start * 1024) >> 12)) << 12)]; + pages[c].write_b = mem_write_ramb_page; +***** MEM_NEW.C + + if (byte_dirty_mask) { + free(byte_dirty_mask); + byte_dirty_mask = NULL; + } + byte_dirty_mask = malloc((mem_size * 1024) / 8); + memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); + + if (byte_code_present_mask) { + free(byte_code_present_mask); + byte_code_present_mask = NULL; + } + byte_code_present_mask = malloc((mem_size * 1024) / 8); + memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); + + for (c = 0; c < pages_sz; c++) { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; +***** + +***** mem.c + pages[c].write_l = mem_write_raml_page; + } +***** MEM_NEW.C + pages[c].write_l = mem_write_raml_page; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; + } +***** + +***** mem.c + + mem_set_mem_state(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); + mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); + + flushmmucache(); +} + +void +mem_reset_page_blocks(void) +{ + uint32_t c; + + if (pages == NULL) return; + + for (c = 0; c < pages_sz; c++) { + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; + pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; + } +} + + +void +mem_a20_recalc(void) +{ + int state; + + if (! AT) { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + + return; + } +***** MEM_NEW.C + + memset(_mem_exec, 0x00, sizeof(_mem_exec)); + + memset(&base_mapping, 0x00, sizeof(base_mapping)); + + memset(_mem_state, 0x00, sizeof(_mem_state)); + memset(_mem_state_bak, 0x00, sizeof(_mem_state)); + + mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x0c0000, 0x40000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, + (mem_size > 640) ? 0xa0000 : mem_size * 1024, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram, MEM_MAPPING_INTERNAL, NULL); + + if (mem_size > 1024) { + if (cpu_16bitbus && mem_size > 16256) { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((16256 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + } +***** + +***** mem.c + + state = mem_a20_key | mem_a20_alt; + if (state && !mem_a20_state) { + rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; + flushmmucache(); + } else if (!state && mem_a20_state) { + rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; + flushmmucache(); + } + + mem_a20_state = state; +} +***** MEM_NEW.C + + if (mem_size > 768) + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); + + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, + mem_read_remapped,mem_read_remappedw,mem_read_remappedl, + mem_write_remapped,mem_write_remappedw,mem_write_remappedl, + ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ram_remapped_mapping); + + mem_a20_init(); + + purgable_page_list_head = 0; + purgeable_page_count = 0; +} +***** + +Resync Failed. Files are too different. +***** mem.c +***** MEM_NEW.C + + +void +mem_init(void) +{ + /* Perform a one-time init. */ + ram = rom = NULL; + pages = NULL; +#if DYNAMIC_TABLES + page_lookup = NULL; + readlookup2 = NULL; + writelookup2 = NULL; + +#else + /* Allocate the lookup tables. */ + page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + + readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + + writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); +#endif + +#if FIXME + memset(ff_array, 0xff, sizeof(ff_array)); +#endif + + /* Reset the memory state. */ + mem_reset(); +} + + +void +mem_remap_top(int kb) +{ + int c; + uint32_t start = (mem_size >= 1024) ? mem_size : 1024; + int offset, size = mem_size - 640; + + mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); + if (mem_size <= 640) return; + + if (kb == 0) { + /* Called to disable the mapping. */ + mem_mapping_disable(&ram_remapped_mapping); + + return; + } + + if (size > kb) + size = kb; + + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { + offset = c - ((start * 1024) >> 12); + pages[c].mem = &ram[0xA0000 + (offset << 12)]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; + } + + mem_set_mem_state(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); + mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); + + flushmmucache(); +} + +void +mem_reset_page_blocks(void) +{ + uint32_t c; + + if (pages == NULL) return; + + for (c = 0; c < pages_sz; c++) { + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].block = BLOCK_INVALID; + pages[c].block_2 = BLOCK_INVALID; + } +} + + +void +mem_a20_recalc(void) +{ + int state; + + if (! AT) { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + + return; + } + +***** + diff --git a/src/mem_new.c b/src/mem_new.c deleted file mode 100644 index 84f3aa597..000000000 --- a/src/mem_new.c +++ /dev/null @@ -1,1805 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Memory handling and MMU. - * - * NOTE: Experimenting with dynamically allocated lookup tables; - * the DYNAMIC_TABLES=1 enables this. Will eventually go - * away, either way... - * - * Version: @(#)mem.c 1.0.22 2019/12/02 - * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include "86box.h" -#include "cpu_new/cpu.h" -#include "cpu_new/x86_ops.h" -#include "cpu_new/x86.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" -#include "config.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#ifdef USE_DYNAREC -# include "cpu_new/codegen.h" -#else -# define PAGE_MASK_INDEX_MASK 3 -# define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_MASK 63 -# define PAGE_MASK_SHIFT 4 -#endif - - -#define FIXME 0 -#define DYNAMIC_TABLES 0 /* experimental */ - - -mem_mapping_t base_mapping, - ram_low_mapping, /* 0..640K mapping */ -#if 1 - ram_mid_mapping, -#endif - ram_remapped_mapping, /* 640..1024K mapping */ - ram_high_mapping, /* 1024K+ mapping */ - ram_remapped_mapping, - ram_split_mapping, - bios_mapping, - bios_high_mapping; - -page_t *pages, /* RAM page table */ - **page_lookup; /* pagetable lookup */ -uint32_t pages_sz; /* #pages in table */ - -uint8_t *ram; /* the virtual RAM */ -uint32_t rammask; - -uint8_t *rom; /* the virtual ROM */ -uint32_t biosmask, biosaddr; - -uint32_t pccache; -uint8_t *pccache2; - -int readlnext; -int readlookup[256], - readlookupp[256]; -uintptr_t *readlookup2; -int writelnext; -int writelookup[256], - writelookupp[256]; -uintptr_t *writelookup2; - -uint32_t mem_logical_addr; - -int shadowbios = 0, - shadowbios_write; -int readlnum = 0, - writelnum = 0; -int cachesize = 256; - -uint32_t get_phys_virt, - get_phys_phys; - -int mem_a20_key = 0, - mem_a20_alt = 0, - mem_a20_state = 0; - -int mmuflush = 0; -int mmu_perm = 4; - -uint64_t *byte_dirty_mask; -uint64_t *byte_code_present_mask; - -uint32_t purgable_page_list_head = 0; -int purgeable_page_count = 0; - - -/* FIXME: re-do this with a 'mem_ops' struct. */ -static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; -static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; -static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static int _mem_state[MEM_MAPPINGS_NO]; - -#if FIXME -#if (MEM_GRANULARITY_BITS >= 12) -static uint8_t ff_array[MEM_GRANULARITY_SIZE]; -#else -static uint8_t ff_array[4096]; /* Must be at least one page. */ -#endif -#else -static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; -#endif - - -#ifdef ENABLE_MEM_LOG -int mem_do_log = ENABLE_MEM_LOG; - - -static void -mem_log(const char *fmt, ...) -{ - va_list ap; - - if (mem_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define mem_log(fmt, ...) -#endif - - -int -mem_addr_is_ram(uint32_t addr) -{ - mem_mapping_t *mapping = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_remapped_mapping); -} - - -void -resetreadlookup(void) -{ - int c; - - /* This is NULL after app startup, when mem_init() has not yet run. */ -#if DYNAMIC_TABLES -mem_log("MEM: reset_lookup: pages=%08lx, lookup=%08lx, pages_sz=%i\n", pages, page_lookup, pages_sz); -#endif - - /* Initialize the page lookup table. */ -#if DYNAMIC_TABLES - memset(page_lookup, 0x00, pages_sz*sizeof(page_t *)); -#else - memset(page_lookup, 0x00, (1<<20)*sizeof(page_t *)); -#endif - - /* Initialize the tables for lower (<= 1024K) RAM. */ - for (c = 0; c < 256; c++) { - readlookup[c] = 0xffffffff; - writelookup[c] = 0xffffffff; - } - - /* Initialize the tables for high (> 1024K) RAM. */ -#if DYNAMIC_TABLES - memset(readlookup2, 0xff, pages_sz*sizeof(uintptr_t)); - memset(writelookup2, 0xff, pages_sz*sizeof(uintptr_t)); -#else - memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t)); - memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t)); -#endif - - readlnext = 0; - writelnext = 0; - pccache = 0xffffffff; -} - - -void -flushmmucache(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xffffffff; - } - } - mmuflush++; - - pccache = (uint32_t)0xffffffff; - pccache2 = (uint8_t *)0xffffffff; - -#ifdef USE_DYNAREC - codegen_flush(); -#endif -} - - -void -flushmmucache_nopc(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xffffffff; - } - } -} - - -void -flushmmucache_cr3(void) -{ - int c; - - for (c = 0; c < 256; c++) { - if (readlookup[c] != (int) 0xffffffff) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xffffffff; - } - if (writelookup[c] != (int) 0xffffffff) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xffffffff; - } - } -} - - -void -mem_flush_write_page(uint32_t addr, uint32_t virt) -{ - page_t *page_target = &pages[addr >> 12]; - int c; - - for (c = 0; c < 256; c++) { - if (writelookup[c] != (int) 0xffffffff) { - uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; - - if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { - writelookup2[writelookup[c]] = -1; - page_lookup[writelookup[c]] = NULL; - writelookup[c] = 0xffffffff; - } - } - } -} - - -#define mmutranslate_read(addr) mmutranslatereal(addr,0) -#define mmutranslate_write(addr) mmutranslatereal(addr,1) -#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> MEM_GRANULARITY_BITS]))[((x) >> 2) & MEM_GRANULARITY_QMASK] - -uint32_t -mmutranslatereal(uint32_t addr, int rw) -{ - uint32_t temp,temp2,temp3; - uint32_t addr2; - - if (cpu_state.abrt) return -1; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = rammap(addr2); - if (! (temp&1)) { - cr2 = addr; - temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return -1; - } - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - - return -1; - } - - mmu_perm = temp & 4; - rammap(addr2) |= 0x20; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || cr0&WP_FLAG))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return -1; - } - - mmu_perm = temp & 4; - rammap(addr2) |= 0x20; - rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw?0x60:0x20); - - return (temp&~0xfff)+(addr&0xfff); -} - - -uint32_t -mmutranslate_noabrt(uint32_t addr, int rw) -{ - uint32_t temp,temp2,temp3; - uint32_t addr2; - - if (cpu_state.abrt) - return -1; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = rammap(addr2); - - if (! (temp & 1)) - return -1; - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) - return -1; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; - - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) - return -1; - - return (temp & ~0xfff) + (addr & 0xfff); -} - - -void -mmu_invalidate(uint32_t addr) -{ - flushmmucache_cr3(); -} - - -uint8_t -mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len) -{ - if (addr < start) - return 0; - else if (addr >= (start + len)) - return 0; - else - return 1; -} - - -uint32_t -mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) -{ - uint32_t mask = len - 1; - - return chunk_start + (addr & mask); -} - - -void -addreadlookup(uint32_t virt, uint32_t phys) -{ - if (virt == 0xffffffff) return; - - if (readlookup2[virt>>12] != (uintptr_t) -1) return; - - if (readlookup[readlnext] != (int) 0xffffffff) - readlookup2[readlookup[readlnext]] = -1; - - readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - - readlookupp[readlnext] = mmu_perm; - readlookup[readlnext++] = virt >> 12; - readlnext &= (cachesize-1); - - sub_cycles(9); -} - - -void -addwritelookup(uint32_t virt, uint32_t phys) -{ - if (virt == 0xffffffff) return; - - if (page_lookup[virt >> 12]) return; - - if (writelookup[writelnext] != -1) { - page_lookup[writelookup[writelnext]] = NULL; - writelookup2[writelookup[writelnext]] = -1; - } - - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) - page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - else - writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - - writelookupp[writelnext] = mmu_perm; - writelookup[writelnext++] = virt >> 12; - writelnext &= (cachesize - 1); - - sub_cycles(9); -} - - -uint8_t * -getpccache(uint32_t a) -{ - uint32_t a2; - - a2 = a; - - if (cr0 >> 31) { - a = mmutranslate_read(a); - - if (a == 0xffffffff) return ram; - } - a &= rammask; - - if (_mem_exec[a >> MEM_GRANULARITY_BITS]) { - if (is286) { - if (read_mapping[a >> MEM_GRANULARITY_BITS] && (read_mapping[a >> MEM_GRANULARITY_BITS]->flags & MEM_MAPPING_ROM)) - cpu_prefetch_cycles = cpu_rom_prefetch_cycles; - else - cpu_prefetch_cycles = cpu_mem_prefetch_cycles; - } - - return &_mem_exec[a >> MEM_GRANULARITY_BITS][(uintptr_t)(a & MEM_GRANULARITY_PAGE) - (uintptr_t)(a2 & ~0xfff)]; - } - - mem_log("Bad getpccache %08X\n", a); - -#if FIXME - return &ff_array[0-(uintptr_t)(a2 & ~0xfff)]; -#else - return (uint8_t *)&ff_pccache; -#endif -} - - -uint8_t -readmembl(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) return 0xFF; - } - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_b) - return map->read_b(addr, map->p); - return 0xFF; -} - - -void -writemembl(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0 >> 31) { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) - return; - } - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->write_b) - return map->write_b(addr, val, map->p); -} - - -uint16_t -readmemwl(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFFE) { - if (cr0 >> 31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffff; - if (mmutranslate_read(addr+1) == 0xffffffff) - return 0xffff; - } - return readmembl(addr)|(readmembl(addr+1)<<8); - } else if (readlookup2[addr >> 12] != -1) - return *(uint16_t *)(readlookup2[addr >> 12] + addr); - } - if (cr0>>31) { - addr = mmutranslate_read(addr); - if (addr==0xFFFFFFFF) - return 0xFFFF; - } - - addr &= rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->read_w) - return map->read_w(addr, map->p); - - if (map->read_b) - return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); - } - - return 0xffff; -} - - -void -writememwl(uint32_t addr, uint16_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFFE) { - if (cr0 >> 31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr+1) == 0xffffffff) - return; - } - writemembl(addr,val); - writemembl(addr+1,val>>8); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0>>31) { - addr = mmutranslate_write(addr); - if (addr==0xFFFFFFFF) - return; - } - - addr &= rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_w) - map->write_w(addr, val, map->p); - else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - } - } -} - - -uint32_t -readmemll(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - sub_cycles(timing_misaligned); - if ((addr&0xFFF)>0xFFC) { - if (cr0>>31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffffffff; - if (mmutranslate_read(addr+3) == 0xffffffff) - return 0xffffffff; - } - return readmemwl(addr)|(readmemwl(addr+2)<<16); - } else if (readlookup2[addr >> 12] != -1) - return *(uint32_t *)(readlookup2[addr >> 12] + addr); - } - - if (cr0>>31) { - addr = mmutranslate_read(addr); - if (addr==0xFFFFFFFF) - return 0xFFFFFFFF; - } - - addr&=rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->read_l) - return map->read_l(addr, map->p); - - if (map->read_w) - return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); - - if (map->read_b) - return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | - (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); - } - - return 0xffffffff; -} - - -void -writememll(uint32_t addr, uint32_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFFC) { - if (cr0>>31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr+3) == 0xffffffff) - return; - } - writememwl(addr,val); - writememwl(addr+2,val>>16); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0>>31) { - addr = mmutranslate_write(addr); - if (addr==0xFFFFFFFF) - return; - } - - addr&=rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_l) - map->write_l(addr, val, map->p); - else if (map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - } else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - } - } -} - - -uint64_t -readmemql(uint32_t addr) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 7) { - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFF8) { - if (cr0>>31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffffffff; - if (mmutranslate_read(addr+7) == 0xffffffff) - return 0xffffffff; - } - return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); - } else if (readlookup2[addr >> 12] != -1) - return *(uint64_t *)(readlookup2[addr >> 12] + addr); - } - - if (cr0>>31) { - addr = mmutranslate_read(addr); - if (addr==0xFFFFFFFF) - return 0xFFFFFFFF; - } - - addr&=rammask; - - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map && map->read_l) - return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); - - return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); -} - - -void -writememql(uint32_t addr, uint64_t val) -{ - mem_mapping_t *map; - - mem_logical_addr = addr; - - if (addr & 7) { - sub_cycles(timing_misaligned); - if ((addr & 0xFFF) > 0xFF8) { - if (cr0>>31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr+7) == 0xffffffff) - return; - } - writememll(addr, val); - writememll(addr+4, val >> 32); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - if (page_lookup[addr>>12]) { - page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); - page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); - return; - } - if (cr0>>31) { - addr = mmutranslate_write(addr); - if (addr==0xFFFFFFFF) - return; - } - - addr&=rammask; - - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - if (map) { - if (map->write_l) { - map->write_l(addr, val, map->p); - map->write_l(addr + 4, val >> 32, map->p); - } else if (map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - map->write_w(addr + 4, val >> 32, map->p); - map->write_w(addr + 6, val >> 48, map->p); - } else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - map->write_b(addr + 4, val >> 32, map->p); - map->write_b(addr + 5, val >> 40, map->p); - map->write_b(addr + 6, val >> 48, map->p); - map->write_b(addr + 7, val >> 56, map->p); - } - } -} - - -int -mem_mapping_is_romcs(uint32_t addr, int write) -{ - mem_mapping_t *map; - - if (write) - map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - else - map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (map) - return !!(map->flags & MEM_MAPPING_ROMCS); - else - return 0; -} - - -uint8_t -mem_readb_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - return _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]; - else if (map && map->read_b) - return map->read_b(addr, map->p); - else - return 0xff; -} - - -uint16_t -mem_readw_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - uint16_t temp; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - return ((uint16_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK]; - else if (map && map->read_w) - return map->read_w(addr, map->p); - else { - temp = mem_readb_phys(addr + 1) << 8; - temp |= mem_readb_phys(addr); - } - - return temp; -} - -uint32_t -mem_readl_phys(uint32_t addr) -{ - mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - uint32_t temp; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - return ((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK]; - else if (map && map->read_l) - return map->read_l(addr, map->p); - else { - temp = mem_readb_phys(addr + 3) << 24; - temp |= mem_readb_phys(addr + 2) << 16; - temp |= mem_readb_phys(addr + 1) << 8; - temp |= mem_readb_phys(addr); - } - - return temp; -} - - -void -mem_writeb_phys(uint32_t addr, uint8_t val) -{ - mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val; - else if (map && map->write_b) - map->write_b(addr, val, map->p); -} - -void -mem_writel_phys(uint32_t addr, uint32_t val) -{ - mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; - - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) - _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val; - else if (map && map->write_l) - map->write_l(addr, val, map->p); - else - { - mem_writeb_phys(addr, val & 0xff); - mem_writeb_phys(addr + 1, (val >> 8) & 0xff); - mem_writeb_phys(addr + 2, (val >> 16) & 0xff); - mem_writeb_phys(addr + 3, (val >> 24) & 0xff); - } -} - -uint8_t -mem_read_ram(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - - return ram[addr]; -} - - -uint16_t -mem_read_ramw(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - - return *(uint16_t *)&ram[addr]; -} - - -uint32_t -mem_read_raml(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - - return *(uint32_t *)&ram[addr]; -} - - -static inline int -page_index(page_t *p) -{ - return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); -} - - -void -page_add_to_evict_list(page_t *p) -{ - pages[purgable_page_list_head].evict_prev = page_index(p); - p->evict_next = purgable_page_list_head; - p->evict_prev = 0; - purgable_page_list_head = pages[purgable_page_list_head].evict_prev; - purgeable_page_count++; -} - - -void -page_remove_from_evict_list(page_t *p) -{ - if (!page_in_evict_list(p)) - fatal("page_remove_from_evict_list: not in evict list!\n"); - if (p->evict_prev) - pages[p->evict_prev].evict_next = p->evict_next; - else - purgable_page_list_head = p->evict_next; - if (p->evict_next) - pages[p->evict_next].evict_prev = p->evict_prev; - p->evict_prev = EVICT_NOT_IN_LIST; - purgeable_page_count--; -} - - -void -mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) -{ - if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); - - p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - p->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - - -void -mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) -{ - if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); - - if ((addr & 0xf) == 0xf) - mask |= (mask << 1); - *(uint16_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { - p->byte_dirty_mask[byte_offset+1] |= 1; - if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } else - byte_mask |= (byte_mask << 1); - - p->byte_dirty_mask[byte_offset] |= byte_mask; - - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - - -void -mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) -{ - if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); - - if ((addr & 0xf) >= 0xd) - mask |= (mask << 1); - *(uint32_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - p->byte_dirty_mask[byte_offset] |= byte_mask; - if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) - page_add_to_evict_list(p); - if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) { - uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); - - p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; - if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } - } -} - - -void -mem_write_ram(uint32_t addr, uint8_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[addr >> 12]); -} - - -void -mem_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[addr >> 12]); -} - - -void -mem_write_raml(uint32_t addr, uint32_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[addr >> 12]); -} - - -static uint8_t -mem_read_remapped(uint32_t addr, void *priv) -{ - if(addr >= (mem_size * 1024) && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addreadlookup(mem_logical_addr, addr); - return ram[addr]; -} - - -static uint16_t -mem_read_remappedw(uint32_t addr, void *priv) -{ - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *)&ram[addr]; -} - - -static uint32_t -mem_read_remappedl(uint32_t addr, void *priv) -{ - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *)&ram[addr]; -} - - -static void -mem_write_remapped(uint32_t addr, uint8_t val, void *priv) -{ - uint32_t oldaddr = addr; - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); -} - - -static void -mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) -{ - uint32_t oldaddr = addr; - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); -} - - -static void -mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) -{ - uint32_t oldaddr = addr; - if(addr >= mem_size * 1024 && addr < ((mem_size + 384) * 1024)) - addr = 0xA0000 + (addr - (mem_size * 1024)); - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); -} - - -uint8_t -mem_read_bios(uint32_t addr, void *priv) -{ - uint8_t ret = 0xff; - - addr &= 0x000fffff; - - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = rom[addr - biosaddr]; - - return ret; -} - - -uint16_t -mem_read_biosw(uint32_t addr, void *priv) -{ - uint16_t ret = 0xffff; - - addr &= 0x000fffff; - - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = *(uint16_t *)&rom[addr - biosaddr]; - - return ret; -} - - -uint32_t -mem_read_biosl(uint32_t addr, void *priv) -{ - uint32_t ret = 0xffffffff; - - addr &= 0x000fffff; - - if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) - ret = *(uint32_t *)&rom[addr - biosaddr]; - - return ret; -} - - -void -mem_write_null(uint32_t addr, uint8_t val, void *p) -{ -} - - -void -mem_write_nullw(uint32_t addr, uint16_t val, void *p) -{ -} - - -void -mem_write_nulll(uint32_t addr, uint32_t val, void *p) -{ -} - - -void -mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) -{ - uint64_t mask; - page_t *p; - - start_addr &= ~PAGE_MASK_MASK; - end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - - for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { - if ((start_addr >> 12) >= pages_sz) - continue; - - mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - - p = &pages[start_addr >> 12]; - - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - } -} - - -static __inline int -mem_mapping_read_allowed(uint32_t flags, int state) -{ - switch (state & MEM_READ_MASK) { - case MEM_READ_DISABLED: - return 0; - - case MEM_READ_ANY: - return 1; - - /* On external and 0 mappings without ROMCS. */ - case MEM_READ_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); - - /* On external and 0 mappings with ROMCS. */ - case MEM_READ_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); - - /* On any external mappings. */ - case MEM_READ_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); - - case MEM_READ_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); - - default: - fatal("mem_mapping_read_allowed : bad state %x\n", state); - } - - return 0; -} - - -static __inline int -mem_mapping_write_allowed(uint32_t flags, int state) -{ - switch (state & MEM_WRITE_MASK) { - case MEM_WRITE_DISABLED: - return 0; - - case MEM_WRITE_ANY: - return 1; - - /* On external and 0 mappings without ROMCS. */ - case MEM_WRITE_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); - - /* On external and 0 mappings with ROMCS. */ - case MEM_WRITE_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); - - /* On any external mappings. */ - case MEM_WRITE_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); - - case MEM_WRITE_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); - - default: - fatal("mem_mapping_write_allowed : bad state %x\n", state); - } - - return 0; -} - - -static void -mem_mapping_recalc(uint64_t base, uint64_t size) -{ - mem_mapping_t *map = base_mapping.next; - uint64_t c; - - if (! size) return; - - /* Clear out old mappings. */ - for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { - read_mapping[c >> MEM_GRANULARITY_BITS] = NULL; - write_mapping[c >> MEM_GRANULARITY_BITS] = NULL; - _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - } - - /* Walk mapping list. */ - while (map != NULL) { - /*In range?*/ - if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) { - uint64_t start = (map->base < base) ? map->base : base; - uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64_t)map->size) : (base + size); - if (start < map->base) - start = map->base; - - for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { - if ((map->read_b || map->read_w || map->read_l) && - mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { - read_mapping[c >> MEM_GRANULARITY_BITS] = map; - if (map->exec) - _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); - else - _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; - } - if ((map->write_b || map->write_w || map->write_l) && - mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) - write_mapping[c >> MEM_GRANULARITY_BITS] = map; - } - } - map = map->next; - } - - flushmmucache_cr3(); -} - - -void -mem_mapping_del(mem_mapping_t *map) -{ - mem_mapping_t *ptr; - - /* Disable the entry. */ - mem_mapping_disable(map); - - /* Zap it from the list. */ - for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) { - if (ptr->next == map) { - ptr->next = map->next; - break; - } - } -} - - -void -mem_mapping_add(mem_mapping_t *map, - uint32_t base, - uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), - uint8_t *exec, - uint32_t fl, - void *p) -{ - mem_mapping_t *dest = &base_mapping; - - /* Add mapping to the end of the list.*/ - while (dest->next) - dest = dest->next; - dest->next = map; - map->prev = dest; - - if (size) - map->enable = 1; - else - map->enable = 0; - map->base = base; - map->size = size; - map->read_b = read_b; - map->read_w = read_w; - map->read_l = read_l; - map->write_b = write_b; - map->write_w = write_w; - map->write_l = write_l; - map->exec = exec; - map->flags = fl; - map->p = p; - map->dev = NULL; - map->next = NULL; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_handler(mem_mapping_t *map, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p)) -{ - map->read_b = read_b; - map->read_w = read_w; - map->read_l = read_l; - map->write_b = write_b; - map->write_w = write_w; - map->write_l = write_l; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) -{ - /* Remove old mapping. */ - map->enable = 0; - mem_mapping_recalc(map->base, map->size); - - /* Set new mapping. */ - map->enable = 1; - map->base = base; - map->size = size; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) -{ - map->exec = exec; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_set_p(mem_mapping_t *map, void *p) -{ - map->p = p; -} - - -void -mem_mapping_set_dev(mem_mapping_t *map, void *p) -{ - map->dev = p; -} - - -void -mem_mapping_disable(mem_mapping_t *map) -{ - map->enable = 0; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_mapping_enable(mem_mapping_t *map) -{ - map->enable = 1; - - mem_mapping_recalc(map->base, map->size); -} - - -void -mem_set_mem_state(uint32_t base, uint32_t size, int state) -{ - uint32_t c; - - for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) - _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state; - - mem_mapping_recalc(base, size); -} - - -void -mem_add_bios(void) -{ - if (biosmask > 0x1ffff) { - /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ - mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - - mem_set_mem_state(0x0e0000, 0x20000, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); - } else { - mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - - mem_set_mem_state(biosaddr, biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); - } - - if (AT) { - mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, - mem_read_bios,mem_read_biosw,mem_read_biosl, - mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - - mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); - } -} - - -void -mem_a20_init(void) -{ - if (AT) { - rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; - flushmmucache(); - mem_a20_state = mem_a20_key | mem_a20_alt; - } else { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - } -} - - -/* Reset the memory state. */ -void -mem_reset(void) -{ - uint32_t c, m; - - m = 1024UL * mem_size; - if (ram != NULL) { - free(ram); - ram = NULL; - } - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - memset(ram, 0x00, m); - - /* - * Allocate the page table based on how much RAM we have. - * We re-allocate the table on each (hard) reset, as the - * memory amount could have changed. - */ - if (AT) { - if (cpu_16bitbus) { - /* 80186/286; maximum address space is 16MB. */ - m = 4096; - } else { - /* 80386+; maximum address space is 4GB. */ - m = (mem_size + 384) >> 2; - if ((m << 2) < (mem_size + 384)) - m++; - if (m < 4096) - m = 4096; - } - } else { - /* 8088/86; maximum address space is 1MB. */ - m = 256; - } - - /* - * Allocate and initialize the (new) page table. - * We only do this if the size of the page table has changed. - */ -#if DYNAMIC_TABLES -mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); -#endif - if (pages_sz != m) { - pages_sz = m; - if (pages) { - free(pages); - pages = NULL; - } - pages = (page_t *)malloc(m*sizeof(page_t)); -#if DYNAMIC_TABLES -mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); -#endif - -#if DYNAMIC_TABLES - /* Allocate the (new) lookup tables. */ - if (page_lookup != NULL) free(page_lookup); - page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); - - if (readlookup2 != NULL) free(readlookup2); - readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); - - if (writelookup2 != NULL) free(writelookup2); - writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); - -#endif - } - -#if DYNAMIC_TABLES - memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); -#else - memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); -#endif - - memset(pages, 0x00, pages_sz*sizeof(page_t)); - - - if (byte_dirty_mask) { - free(byte_dirty_mask); - byte_dirty_mask = NULL; - } - byte_dirty_mask = malloc((mem_size * 1024) / 8); - memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); - - if (byte_code_present_mask) { - free(byte_code_present_mask); - byte_code_present_mask = NULL; - } - byte_code_present_mask = malloc((mem_size * 1024) / 8); - memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); - - for (c = 0; c < pages_sz; c++) { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; - } - - memset(_mem_exec, 0x00, sizeof(_mem_exec)); - - memset(&base_mapping, 0x00, sizeof(base_mapping)); - - memset(_mem_state, 0x00, sizeof(_mem_state)); - - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0c0000, 0x40000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - - mem_mapping_add(&ram_low_mapping, 0x00000, - (mem_size > 640) ? 0xa0000 : mem_size * 1024, - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram, MEM_MAPPING_INTERNAL, NULL); - - if (mem_size > 1024) { - if (cpu_16bitbus && mem_size > 16256) { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, - ((16256 - 1024) * 1024), - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } else { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, - ((mem_size - 1024) * 1024), - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - } - - if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, - mem_read_remapped,mem_read_remappedw,mem_read_remappedl, - mem_write_remapped,mem_write_remappedw,mem_write_remappedl, - ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); - - mem_a20_init(); - - purgable_page_list_head = 0; - purgeable_page_count = 0; -} - - -void -mem_init(void) -{ - /* Perform a one-time init. */ - ram = rom = NULL; - pages = NULL; -#if DYNAMIC_TABLES - page_lookup = NULL; - readlookup2 = NULL; - writelookup2 = NULL; - -#else - /* Allocate the lookup tables. */ - page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); - - readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); - - writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); -#endif - -#if FIXME - memset(ff_array, 0xff, sizeof(ff_array)); -#endif - - /* Reset the memory state. */ - mem_reset(); -} - - -void -mem_remap_top(int kb) -{ - int c; - uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int offset, size = mem_size - 640; - - mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); - if (mem_size <= 640) return; - - if (kb == 0) { - /* Called to disable the mapping. */ - mem_mapping_disable(&ram_remapped_mapping); - - return; - } - - if (size > kb) - size = kb; - - for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - offset = c - ((start * 1024) >> 12); - pages[c].mem = &ram[0xA0000 + (offset << 12)]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; - } - - mem_set_mem_state(start * 1024, size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); - mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); - - flushmmucache(); -} - -void -mem_reset_page_blocks(void) -{ - uint32_t c; - - if (pages == NULL) return; - - for (c = 0; c < pages_sz; c++) { - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].block = BLOCK_INVALID; - pages[c].block_2 = BLOCK_INVALID; - } -} - - -void -mem_a20_recalc(void) -{ - int state; - - if (! AT) { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - - return; - } - - state = mem_a20_key | mem_a20_alt; - if (state && !mem_a20_state) { - rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; - flushmmucache(); - } else if (!state && mem_a20_state) { - rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; - flushmmucache(); - } - - mem_a20_state = state; -} diff --git a/src/midi.d b/src/midi.d new file mode 100644 index 000000000..1cc8ed511 --- /dev/null +++ b/src/midi.d @@ -0,0 +1,2 @@ +midi.o: sound/midi.c 86box.h device.h plat.h lang/language.h plat_midi.h \ + sound/midi.h sound/midi_input.h diff --git a/src/midi_fluidsynth.d b/src/midi_fluidsynth.d new file mode 100644 index 000000000..724273e0f --- /dev/null +++ b/src/midi_fluidsynth.d @@ -0,0 +1,2 @@ +midi_fluidsynth.o: sound/midi_fluidsynth.c 86box.h config.h device.h \ + plat.h lang/language.h plat_dynld.h ui.h sound/midi.h sound/sound.h diff --git a/src/midi_mt32.d b/src/midi_mt32.d new file mode 100644 index 000000000..6a8ef07f2 --- /dev/null +++ b/src/midi_mt32.d @@ -0,0 +1,5 @@ +midi_mt32.o: sound/midi_mt32.c sound/munt/c_interface/c_interface.h \ + sound/munt/c_interface/../globals.h sound/munt/c_interface/../config.h \ + sound/munt/c_interface/c_types.h \ + sound/munt/c_interface/../Enumerations.h 86box.h device.h mem.h rom.h \ + plat.h lang/language.h sound/sound.h sound/midi.h diff --git a/src/midi_system.d b/src/midi_system.d new file mode 100644 index 000000000..aaad57f7f --- /dev/null +++ b/src/midi_system.d @@ -0,0 +1,2 @@ +midi_system.o: sound/midi_system.c 86box.h device.h plat.h \ + lang/language.h plat_midi.h sound/midi.h sound/midi_input.h diff --git a/src/misc.d b/src/misc.d new file mode 100644 index 000000000..ce9c7eb5d --- /dev/null +++ b/src/misc.d @@ -0,0 +1,8 @@ +misc.o: network/slirp/misc.c network/slirp/slirp.h network/slirp/config.h \ + network/slirp/config-host.h network/slirp/slirp_config.h \ + network/slirp/debug.h network/slirp/ip.h network/slirp/tcp.h \ + network/slirp/tcp_var.h network/slirp/tcpip.h network/slirp/tcp_timer.h \ + network/slirp/udp.h network/slirp/icmp_var.h network/slirp/mbuf.h \ + network/slirp/sbuf.h network/slirp/socket.h network/slirp/if.h \ + network/slirp/main.h network/slirp/misc.h network/slirp/ctl.h \ + network/slirp/bootp.h network/slirp/tftp.h network/slirp/libslirp.h diff --git a/src/mouse.d b/src/mouse.d new file mode 100644 index 000000000..c433c6a3b --- /dev/null +++ b/src/mouse.d @@ -0,0 +1 @@ +mouse.o: mouse.c 86box.h device.h mouse.h diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 36b039d28..df7794adf 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -75,7 +75,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "pic.h" #include "timer.h" #include "device.h" diff --git a/src/mouse_bus.d b/src/mouse_bus.d new file mode 100644 index 000000000..25d04de2b --- /dev/null +++ b/src/mouse_bus.d @@ -0,0 +1,2 @@ +mouse_bus.o: mouse_bus.c 86box.h 86box_io.h pic.h timer.h \ + cpu_common/cpu.h device.h mouse.h random.h diff --git a/src/mouse_ps2.d b/src/mouse_ps2.d new file mode 100644 index 000000000..7c0e68e70 --- /dev/null +++ b/src/mouse_ps2.d @@ -0,0 +1 @@ +mouse_ps2.o: mouse_ps2.c 86box.h device.h keyboard.h mouse.h diff --git a/src/mouse_serial.d b/src/mouse_serial.d new file mode 100644 index 000000000..9a1a0b89d --- /dev/null +++ b/src/mouse_serial.d @@ -0,0 +1,2 @@ +mouse_serial.o: mouse_serial.c 86box.h device.h timer.h cpu_common/cpu.h \ + serial.h mouse.h diff --git a/src/neat.d b/src/neat.d new file mode 100644 index 000000000..9be1ba93f --- /dev/null +++ b/src/neat.d @@ -0,0 +1,3 @@ +neat.o: chipset/neat.c 86box.h device.h timer.h cpu_common/cpu.h \ + floppy/fdd.h floppy/fdc.h keyboard.h 86box_io.h mem.h nmi.h \ + chipset/chipset.h diff --git a/src/net_3c503.d b/src/net_3c503.d new file mode 100644 index 000000000..a8a57bff4 --- /dev/null +++ b/src/net_3c503.d @@ -0,0 +1,3 @@ +net_3c503.o: network/net_3c503.c 86box.h 86box_io.h dma.h pic.h mem.h \ + random.h device.h network/network.h network/net_dp8390.h \ + network/net_3c503.h network/bswap.h diff --git a/src/net_dp8390.d b/src/net_dp8390.d new file mode 100644 index 000000000..40288c623 --- /dev/null +++ b/src/net_dp8390.d @@ -0,0 +1,2 @@ +net_dp8390.o: network/net_dp8390.c 86box.h device.h network/network.h \ + network/net_dp8390.h diff --git a/src/net_ne2000.d b/src/net_ne2000.d new file mode 100644 index 000000000..70ee8e265 --- /dev/null +++ b/src/net_ne2000.d @@ -0,0 +1,3 @@ +net_ne2000.o: network/net_ne2000.c 86box.h 86box_io.h mem.h rom.h mca.h \ + pci.h pic.h random.h device.h network/network.h network/net_dp8390.h \ + network/net_ne2000.h network/bswap.h diff --git a/src/net_pcap.d b/src/net_pcap.d new file mode 100644 index 000000000..d2f197880 --- /dev/null +++ b/src/net_pcap.d @@ -0,0 +1,2 @@ +net_pcap.o: network/net_pcap.c 86box.h device.h plat.h lang/language.h \ + plat_dynld.h network/network.h diff --git a/src/net_pcnet.d b/src/net_pcnet.d new file mode 100644 index 000000000..c84d0aa83 --- /dev/null +++ b/src/net_pcnet.d @@ -0,0 +1,3 @@ +net_pcnet.o: network/net_pcnet.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h dma.h mem.h rom.h pci.h pic.h random.h device.h \ + network/network.h network/net_pcnet.h network/bswap.h diff --git a/src/net_slirp.d b/src/net_slirp.d new file mode 100644 index 000000000..b67be0ddc --- /dev/null +++ b/src/net_slirp.d @@ -0,0 +1,10 @@ +net_slirp.o: network/net_slirp.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h network/slirp/queue.h 86box.h device.h plat.h \ + lang/language.h network/network.h diff --git a/src/net_wd8003.d b/src/net_wd8003.d new file mode 100644 index 000000000..52ccbd930 --- /dev/null +++ b/src/net_wd8003.d @@ -0,0 +1,3 @@ +net_wd8003.o: network/net_wd8003.c 86box.h 86box_io.h mem.h rom.h \ + machine/machine.h mca.h pci.h pic.h random.h device.h network/network.h \ + network/net_dp8390.h network/net_wd8003.h network/bswap.h diff --git a/src/network.d b/src/network.d new file mode 100644 index 000000000..165361dd9 --- /dev/null +++ b/src/network.d @@ -0,0 +1,3 @@ +network.o: network/network.c 86box.h device.h plat.h lang/language.h ui.h \ + network/network.h network/net_3c503.h network/net_ne2000.h \ + network/net_pcnet.h network/net_wd8003.h diff --git a/src/network.rar b/src/network.rar new file mode 100644 index 000000000..363c66769 Binary files /dev/null and b/src/network.rar differ diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index 282219ab3..51084ed79 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -48,13 +48,13 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "mem.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" #include "net_3c503.h" @@ -617,7 +617,7 @@ threec503_nic_init(const device_t *info) dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */ /* Attach ourselves to the network module. */ - network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx); + network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); return(dev); } diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index 3c30a23e5..4a062e526 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -23,8 +23,8 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" +#include "86box.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 0fd45626c..8feb13c5c 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -52,15 +52,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../mca.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "mca.h" +#include "pci.h" +#include "pic.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" #include "net_ne2000.h" @@ -1465,7 +1465,7 @@ nic_init(const device_t *info) nic_reset(dev); /* Attach ourselves to the network module. */ - network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx); + network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 771b55e8e..6ca9a2fe3 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -51,11 +51,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -// #include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_dynld.h" #include "network.h" @@ -185,7 +184,7 @@ poll_thread(void *arg) if (pcap == NULL) break; /* Wait for the next packet to arrive. */ - if (network_get_wait()) + if (network_get_wait() || (poll_card->wait && poll_card->wait(poll_card->priv))) data = NULL; else data = (uint8_t *)f_pcap_next((void *)pcap, &h); diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 49de94317..b2370b696 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -31,16 +31,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../mem.h" -#include "../rom.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "mem.h" +#include "rom.h" +#include "pci.h" +#include "pic.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_pcnet.h" #include "bswap.h" @@ -222,14 +222,16 @@ typedef struct { int iLog2DescSize; /** Bits 16..23 in 16-bit mode */ uint32_t GCUpperPhys; + /** We are waitign/about to start waiting for more receive buffers. */ + int fMaybeOutOfSpace; /** True if we signal the guest that RX packets are missing. */ int fSignalRxMiss; /** Link speed to be reported through CSR68. */ uint32_t u32LinkSpeed; /** Error counter for bad receive descriptors. */ uint32_t uCntBadRMD; - uint8_t maclocal[6]; /* configured MAC (local) address */ - pc_timer_t poll_timer; + uint8_t maclocal[6]; /* configured MAC (local) address */ + pc_timer_t poll_timer; } nic_t; /** @todo All structs: big endian? */ @@ -359,10 +361,10 @@ static void pcnetAsyncTransmit(nic_t *dev); static void pcnetPollRxTx(nic_t *dev); static void pcnetPollTimer(nic_t *dev); static void pcnetUpdateIrq(nic_t *dev); -static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap); -static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val); -static void pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val); -static void pcnetCanReceive(nic_t *dev); +static uint16_t pcnet_bcr_readw(nic_t *dev, uint16_t rap); +static void pcnet_bcr_writew(nic_t *dev, uint16_t rap, uint16_t val); +static void pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val); +static int pcnetCanReceive(nic_t *dev); #ifdef ENABLE_PCNET_LOG @@ -1028,6 +1030,13 @@ pcnetStop(nic_t *dev) } +static void +pcnetWakeupReceive(nic_t *dev) +{ + /* TODO: Wake up the thread here. */ +} + + /** * Poll Receive Descriptor Table Entry and cache the results in the appropriate registers. * Note: Once a descriptor belongs to the network card (this driver), it cannot be changed @@ -1062,7 +1071,8 @@ pcnetRdtePoll(nic_t *dev) CSR_CRBA(dev) = rmd.rmd0.rbadr; /* Receive Buffer Address */ CSR_CRBC(dev) = rmd.rmd1.bcnt; /* Receive Byte Count */ CSR_CRST(dev) = ((uint32_t *)&rmd)[1] >> 16; /* Receive Status */ - pcnetCanReceive(dev); + if (dev->fMaybeOutOfSpace) + pcnetWakeupReceive(dev); } else { /* This is not problematic since we don't own the descriptor * We actually do own it, otherwise pcnetRmdLoad would have returned false. @@ -1613,7 +1623,7 @@ pcnetPollRxTx(nic_t *dev) * true but pcnetCanReceive() returned false for some other reason we need to check * _now_ if we have to wakeup pcnetWaitReceiveAvail(). */ - if (HOST_IS_OWNER(CSR_CRST(dev))) + if (HOST_IS_OWNER(CSR_CRST(dev)) || dev->fMaybeOutOfSpace) pcnetRdtePoll(dev); } @@ -1630,8 +1640,8 @@ pcnetPollTimer(nic_t *dev) pcnetUpdateIrq(dev); - if (!CSR_STOP(dev) && !CSR_SPND(dev) && !CSR_DPOLL(dev)) - pcnetPollRxTx(dev); + if (!CSR_STOP(dev) && !CSR_SPND(dev) && (!CSR_DPOLL(dev) || dev->fMaybeOutOfSpace)) + pcnetPollRxTx(dev); } @@ -2449,9 +2459,11 @@ pcnet_pci_read(int func, int addr, void *p) * @returns VBox status code. * @param pThis The PCnet instance data. */ -static void +static int pcnetCanReceive(nic_t *dev) { + int rc = 0; + if (!CSR_DRX(dev) && !CSR_STOP(dev) && !CSR_SPND(dev)) { if (HOST_IS_OWNER(CSR_CRST(dev)) && dev->GCRDRA) pcnetRdtePoll(dev); @@ -2460,8 +2472,22 @@ pcnetCanReceive(nic_t *dev) /** @todo Notify the guest _now_. Will potentially increase the interrupt load */ if (dev->fSignalRxMiss) dev->aCSR[0] |= 0x1000; /* Set MISS flag */ - } + } else + rc = 1; } + + return rc; +} + + +static int +pcnetWaitReceiveAvail(void *priv) +{ + nic_t *dev = (nic_t *) priv; + + dev->fMaybeOutOfSpace = !pcnetCanReceive(dev); + + return dev->fMaybeOutOfSpace; } @@ -2591,7 +2617,7 @@ pcnet_init(const device_t *info) pcnetHardReset(dev); /* Attach ourselves to the network module. */ - network_attach(dev, dev->aPROM, pcnetReceiveNoSync); + network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail); return(dev); } diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 8b8304854..66d26a31b 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -53,10 +53,9 @@ #define HAVE_STDARG_H #include "slirp/slirp.h" #include "slirp/queue.h" -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -// #include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" #include "network.h" @@ -148,7 +147,7 @@ poll_thread(void *arg) /* Wait for the next packet to arrive. */ data_valid = 0; - if (!network_get_wait() && (QueuePeek(slirpq) != 0)) { + if ((!network_get_wait() && !(poll_card->wait && poll_card->wait(poll_card->priv))) && (QueuePeek(slirpq) != 0)) { /* Grab a packet from the queue. */ // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 2148a2142..e11fb1e57 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -48,16 +48,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../machine/machine.h" -#include "../mca.h" -#include "../pci.h" -#include "../pic.h" -#include "../random.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "machine.h" +#include "mca.h" +#include "pci.h" +#include "pic.h" +#include "random.h" +#include "device.h" #include "network.h" #include "net_dp8390.h" #include "net_wd8003.h" @@ -771,7 +771,7 @@ wd_init(const device_t *info) mem_mapping_disable(&dev->ram_mapping); /* Attach ourselves to the network module. */ - network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx); + network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); if (!(dev->board_chip & WE_ID_BUS_MCA)) { wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name, diff --git a/src/network/network.c b/src/network/network.c index 475a3674e..8f441e064 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -55,10 +55,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "ui.h" #include "network.h" #include "net_3c503.h" #include "net_ne2000.h" @@ -219,13 +219,14 @@ network_init(void) * modules. */ void -network_attach(void *dev, uint8_t *mac, NETRXCB rx) +network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait) { if (network_card == 0) return; /* Save the card's info. */ net_cards[network_card].priv = dev; net_cards[network_card].rx = rx; + net_cards[network_card].wait = wait; network_mac = mac; network_set_wait(0); diff --git a/src/network/network.h b/src/network/network.h index feae064ee..7edfabf5c 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -65,6 +65,7 @@ enum { typedef void (*NETRXCB)(void *, uint8_t *, int); +typedef int (*NETWAITCB)(void *); typedef struct { @@ -74,6 +75,7 @@ typedef struct { void *priv; int (*poll)(void *); NETRXCB rx; + NETWAITCB wait; } netcard_t; typedef struct { @@ -99,7 +101,7 @@ extern void network_busy(uint8_t set); extern void network_end(void); extern void network_init(void); -extern void network_attach(void *, uint8_t *, NETRXCB); +extern void network_attach(void *, uint8_t *, NETRXCB, NETWAITCB); extern void network_close(void); extern void network_reset(void); extern int network_available(void); diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index 439dbfa94..b73639b48 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -54,9 +54,9 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" -#include "../plat_dynld.h" +#include "86box.h" +#include "plat.h" +#include "plat_dynld.h" static void *pcap_handle; /* handle to WinPcap DLL */ diff --git a/src/nmi.c b/src/nmi.c index e00061d0c..808113bfa 100644 --- a/src/nmi.c +++ b/src/nmi.c @@ -5,7 +5,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "nmi.h" diff --git a/src/nmi.d b/src/nmi.d new file mode 100644 index 000000000..7bdfc268d --- /dev/null +++ b/src/nmi.d @@ -0,0 +1 @@ +nmi.o: nmi.c 86box_io.h nmi.h diff --git a/src/nukedopl.d b/src/nukedopl.d new file mode 100644 index 000000000..4d6078bc7 --- /dev/null +++ b/src/nukedopl.d @@ -0,0 +1 @@ +nukedopl.o: sound/nukedopl.c sound/nukedopl.h diff --git a/src/nvr.c b/src/nvr.c index bb72ebf2d..28b099ba1 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -55,7 +55,7 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "machine/machine.h" +#include "machine.h" #include "mem.h" #include "timer.h" #include "plat.h" diff --git a/src/nvr.d b/src/nvr.d new file mode 100644 index 000000000..5d9a92bc3 --- /dev/null +++ b/src/nvr.d @@ -0,0 +1,2 @@ +nvr.o: nvr.c 86box.h machine/machine.h mem.h timer.h cpu_common/cpu.h \ + plat.h lang/language.h nvr.h diff --git a/src/nvr.h b/src/nvr.h index 85d54082a..ce283fe92 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -8,7 +8,7 @@ * * Definitions for the generic NVRAM/CMOS driver. * - * Version: @(#)nvr.h 1.0.13 2020/01/20 + * Version: @(#)nvr.h 1.0.14 2020/01/24 * * Author: Fred N. van Kempen, , * David Hrdlička, @@ -50,7 +50,7 @@ # define EMU_NVR_H -#define NVR_MAXSIZE 128 /* max size of NVR data */ +#define NVR_MAXSIZE 256 /* max size of NVR data */ /* Conversion from BCD to Binary and vice versa. */ #define RTC_BCD(x) (((x) % 10) | (((x) / 10) << 4)) @@ -91,6 +91,7 @@ extern const device_t at_nvr_device; extern const device_t ps_nvr_device; extern const device_t amstrad_nvr_device; extern const device_t ibmat_nvr_device; +extern const device_t piix4_nvr_device; extern const device_t ls486e_nvr_device; extern const device_t via_nvr_device; #endif @@ -112,6 +113,7 @@ extern void nvr_time_get(struct tm *); extern void nvr_time_set(struct tm *); extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); +extern void nvr_wp_set(int set, int h, nvr_t *nvr); #endif /*EMU_NVR_H*/ diff --git a/src/nvr_at.c b/src/nvr_at.c index d9a9c692f..deccf7559 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -189,7 +189,7 @@ * including the later update (DS12887A) which implemented a * "century" register to be compatible with Y2K. * - * Version: @(#)nvr_at.c 1.0.18 2020/01/20 + * Version: @(#)nvr_at.c 1.0.19 2020/01/24 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -226,9 +226,9 @@ #include #include #include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" #include "mem.h" #include "nmi.h" #include "pic.h" @@ -293,7 +293,7 @@ typedef struct { uint8_t cent; uint8_t def, ls_hack; - uint8_t addr[8]; + uint8_t addr[8], wp[2]; int16_t count, state; @@ -304,6 +304,9 @@ typedef struct { } local_t; +static uint8_t nvr_at_inited = 0; + + /* Get the current NVR time. */ static void time_get(nvr_t *nvr, struct tm *tm) @@ -593,6 +596,10 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) /*FALLTHROUGH*/ default: /* non-RTC registers are just NVRAM */ + if ((local->addr[addr_id] >= 0x38) && (local->addr[addr_id] <= 0x3f) && local->wp[0]) + break; + if ((local->addr[addr_id] >= 0xb8) && (local->addr[addr_id] <= 0xbf) && local->wp[1]) + break; if (nvr->regs[local->addr[addr_id]] != val) { nvr->regs[local->addr[addr_id]] = val; nvr_dosave = 1; @@ -759,6 +766,15 @@ nvr_at_handler(int set, uint16_t base, nvr_t *nvr) } +void +nvr_wp_set(int set, int h, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->wp[h] = set; +} + + static void * nvr_at_init(const device_t *info) { @@ -824,19 +840,23 @@ nvr_at_init(const device_t *info) /* Initialize the generic NVR. */ nvr_init(nvr); - /* Start the timers. */ - timer_add(&local->update_timer, timer_update, nvr, 0); + if (nvr_at_inited == 0) { + /* Start the timers. */ + timer_add(&local->update_timer, timer_update, nvr, 0); - timer_add(&local->rtc_timer, timer_intr, nvr, 0); - timer_load_count(nvr); - timer_set_delay_u64(&local->rtc_timer, RTCCONST); + timer_add(&local->rtc_timer, timer_intr, nvr, 0); + timer_load_count(nvr); + timer_set_delay_u64(&local->rtc_timer, RTCCONST); - /* Set up the I/O handler for this device. */ - io_sethandler(0x0070, 2, - nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); - if (info->local & 8) { - io_sethandler(0x0072, 2, + /* Set up the I/O handler for this device. */ + io_sethandler(0x0070, 2, nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); + if (info->local & 8) { + io_sethandler(0x0072, 2, + nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr); + } + + nvr_at_inited = 1; } return(nvr); @@ -862,6 +882,9 @@ nvr_at_close(void *priv) free(nvr->data); free(nvr); + + if (nvr_at_inited == 1) + nvr_at_inited = 0; } @@ -910,6 +933,15 @@ const device_t ibmat_nvr_device = { NULL }; +const device_t piix4_nvr_device = { + "Intel PIIX4 PC/AT NVRAM", + DEVICE_ISA | DEVICE_AT, + 9, + nvr_at_init, nvr_at_close, NULL, + NULL, nvr_at_speed_changed, + NULL +}; + const device_t ls486e_nvr_device = { "Lucky Star LS-486E PC/AT NVRAM", DEVICE_ISA | DEVICE_AT, diff --git a/src/nvr_at.d b/src/nvr_at.d new file mode 100644 index 000000000..17e4bf70e --- /dev/null +++ b/src/nvr_at.d @@ -0,0 +1,2 @@ +nvr_at.o: nvr_at.c 86box.h cpu_common/cpu.h machine/machine.h 86box_io.h \ + mem.h nmi.h pic.h timer.h pit.h rom.h device.h nvr.h diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index 483d67529..b4074039d 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -40,9 +40,9 @@ #include #include #include "86box.h" -#include "machine/machine.h" +#include "machine.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "mem.h" #include "timer.h" #include "nvr.h" diff --git a/src/nvr_ps2.d b/src/nvr_ps2.d new file mode 100644 index 000000000..5b1c73443 --- /dev/null +++ b/src/nvr_ps2.d @@ -0,0 +1,2 @@ +nvr_ps2.o: nvr_ps2.c 86box.h machine/machine.h device.h 86box_io.h mem.h \ + timer.h cpu_common/cpu.h nvr.h nvr_ps2.h rom.h diff --git a/src/openal.d b/src/openal.d new file mode 100644 index 000000000..f8d671d9c --- /dev/null +++ b/src/openal.d @@ -0,0 +1 @@ +openal.o: sound/openal.c 86box.h sound/sound.h sound/midi.h diff --git a/src/opti495.d b/src/opti495.d new file mode 100644 index 000000000..afe032937 --- /dev/null +++ b/src/opti495.d @@ -0,0 +1,2 @@ +opti495.o: chipset/opti495.c 86box.h cpu_common/cpu.h timer.h 86box_io.h \ + device.h keyboard.h mem.h floppy/fdd.h floppy/fdc.h chipset/chipset.h diff --git a/src/pc.c b/src/pc.c index 841bb9a23..5fbf1b3a2 100644 --- a/src/pc.c +++ b/src/pc.c @@ -26,24 +26,17 @@ #include #include #include + #define HAVE_STDARG_H #include "86box.h" #include "config.h" #include "mem.h" -#ifdef USE_NEW_DYNAREC +#include "cpu.h" #ifdef USE_DYNAREC -#include "cpu_new/cpu.h" -# include "cpu_new/codegen.h" +# include "codegen_public.h" #endif -#include "cpu_new/x86_ops.h" -#else -#include "cpu/cpu.h" -#ifdef USE_DYNAREC -# include "cpu/codegen.h" -#endif -#include "cpu/x86_ops.h" -#endif -#include "io.h" +#include "x86_ops.h" +#include "86box_io.h" #include "rom.h" #include "dma.h" #include "pci.h" @@ -54,7 +47,7 @@ #include "random.h" #include "timer.h" #include "nvr.h" -#include "machine/machine.h" +#include "machine.h" #include "bugger.h" #include "isamem.h" #include "isartc.h" @@ -62,23 +55,23 @@ #include "serial.h" #include "keyboard.h" #include "mouse.h" -#include "game/gameport.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" -#include "disk/hdd.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "scsi/scsi.h" -#include "scsi/scsi_device.h" -#include "cdrom/cdrom.h" -#include "disk/zip.h" -#include "scsi/scsi_disk.h" -#include "cdrom/cdrom_image.h" -#include "network/network.h" -#include "sound/sound.h" -#include "sound/midi.h" -#include "sound/snd_speaker.h" -#include "video/video.h" +#include "gameport.h" +#include "fdd.h" +#include "fdc.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "scsi_disk.h" +#include "cdrom_image.h" +#include "network.h" +#include "sound.h" +#include "midi.h" +#include "snd_speaker.h" +#include "video.h" #include "ui.h" #include "plat.h" #include "plat_midi.h" diff --git a/src/pc.d b/src/pc.d new file mode 100644 index 000000000..e022ac9c2 --- /dev/null +++ b/src/pc.d @@ -0,0 +1,9 @@ +pc.o: pc.c 86box.h config.h mem.h cpu_common/cpu.h \ + cpu_common/codegen_public.h cpu_common/x86_ops.h 86box_io.h rom.h dma.h \ + pci.h pic.h timer.h device.h pit.h random.h nvr.h machine/machine.h \ + bugger.h isamem.h isartc.h lpt.h serial.h keyboard.h mouse.h \ + game/gameport.h floppy/fdd.h floppy/fdc.h disk/hdd.h disk/hdc.h \ + disk/hdc_ide.h scsi/scsi.h scsi/scsi_device.h cdrom/cdrom.h disk/zip.h \ + scsi/scsi_disk.h cdrom/cdrom_image.h network/network.h sound/sound.h \ + sound/midi.h sound/snd_speaker.h video/video.h ui.h plat.h \ + lang/language.h plat_midi.h diff --git a/src/pcap_if.d b/src/pcap_if.d new file mode 100644 index 000000000..f42b7dbdf --- /dev/null +++ b/src/pcap_if.d @@ -0,0 +1 @@ +pcap_if.o: network/pcap_if.c 86box.h plat.h lang/language.h plat_dynld.h diff --git a/src/pci.c b/src/pci.c index 082361c36..4e7eb1eba 100644 --- a/src/pci.c +++ b/src/pci.c @@ -25,9 +25,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "machine/machine.h" -#include "cpu/cpu.h" -#include "io.h" +#include "machine.h" +#include "cpu.h" +#include "86box_io.h" #include "pic.h" #include "mem.h" #include "device.h" @@ -235,10 +235,12 @@ pci_type2_write(uint16_t port, uint8_t val, void *priv) if (! pci_bus) { slot = pci_card_to_slot_mapping[pci_card]; if (slot != 0xff) { - if (pci_cards[slot].write) { + if (pci_cards[slot].write) pci_cards[slot].write(pci_func, pci_index | (port & 3), val, pci_cards[slot].priv); - } - } + else + pclog("Writing to empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); + } else + pclog("Writing to unassigned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); } } } @@ -261,10 +263,12 @@ pci_type2_read(uint16_t port, void *priv) if (! pci_bus) { slot = pci_card_to_slot_mapping[pci_card]; if (slot != 0xff) { - if (pci_cards[slot].read) { + if (pci_cards[slot].read) return pci_cards[slot].read(pci_func, pci_index | (port & 3), pci_cards[slot].priv); - } - } + else + pclog("Reading from empty PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); + } else + pclog("Reading from unasisgned PCI card on slot %02X (pci_cards[%i]) (%02X:%02X)...\n", pci_card, slot, pci_func, pci_index); } return 0xff; @@ -613,7 +617,7 @@ pci_slots_clear(void) } -static uint8_t +uint8_t trc_read(uint16_t port, void *priv) { return trc_reg & 0xfb; @@ -628,23 +632,24 @@ trc_reset(uint8_t val) cpu_alt_reset = 0; + pci_reset(); + keyboard_at_reset(); + mem_a20_alt = 0; mem_a20_recalc(); flushmmucache(); - - pci_reset(); - keyboard_at_reset(); } resetx86(); } -static void +void trc_write(uint16_t port, uint8_t val, void *priv) { pci_log("TRC Write: %02X\n", val); + pclog("[%04X:%08X] TRC Write: %02X\n", CS, cpu_state.pc, val); if (!(trc_reg & 4) && (val & 4)) trc_reset(val); @@ -760,7 +765,9 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), if (((dev->type == PCI_CARD_NORMAL) && (add_type >= PCI_ADD_NORMAL)) || ((dev->type == PCI_CARD_ONBOARD) && (add_type == PCI_ADD_VIDEO)) || ((dev->type == PCI_CARD_SCSI) && (add_type == PCI_ADD_SCSI)) || - ((dev->id == add_type) && (add_type < PCI_ADD_NORMAL))) { + ((dev->type == PCI_CARD_NORTHBRIDGE) && (add_type == PCI_ADD_NORTHBRIDGE)) || + ((dev->type == PCI_CARD_SOUTHBRIDGE) && (add_type == PCI_ADD_SOUTHBRIDGE)) || + ((dev->id == add_type) && (add_type < PCI_ADD_NORTHBRIDGE))) { dev->read = read; dev->write = write; dev->priv = priv; diff --git a/src/pci.d b/src/pci.d new file mode 100644 index 000000000..04a8094bb --- /dev/null +++ b/src/pci.d @@ -0,0 +1,2 @@ +pci.o: pci.c 86box.h machine/machine.h cpu_common/cpu.h 86box_io.h pic.h \ + mem.h device.h pci.h piix.h keyboard.h diff --git a/src/pci.h b/src/pci.h index 18a93d9fb..473f27389 100644 --- a/src/pci.h +++ b/src/pci.h @@ -46,16 +46,21 @@ #define PCI_IRQ_DISABLED -1 enum { - PCI_CARD_NORMAL = 0, + PCI_CARD_NORTHBRIDGE = 0, + PCI_CARD_SOUTHBRIDGE, + PCI_CARD_NORMAL, PCI_CARD_ONBOARD, PCI_CARD_SCSI, PCI_CARD_SPECIAL }; - -#define PCI_ADD_NORMAL 0x80 -#define PCI_ADD_VIDEO 0x81 -#define PCI_ADD_SCSI 0x82 +enum { + PCI_ADD_NORTHBRIDGE = 0x80, + PCI_ADD_SOUTHBRIDGE, + PCI_ADD_NORMAL, + PCI_ADD_VIDEO, + PCI_ADD_SCSI +}; typedef union { uint32_t addr; @@ -90,6 +95,10 @@ extern void pci_close(void); extern uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); extern void trc_init(void); + +extern uint8_t trc_read(uint16_t port, void *priv); +extern void trc_write(uint16_t port, uint8_t val, void *priv); + extern void pci_elcr_set_enabled(int enabled); diff --git a/src/pci_dummy.c b/src/pci_dummy.c index 6a790ff14..02819618b 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -4,7 +4,7 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "pci.h" #include "pci_dummy.h" diff --git a/src/pic.c b/src/pic.c index 12cbcb251..ac13841e6 100644 --- a/src/pic.c +++ b/src/pic.c @@ -21,9 +21,9 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" -#include "machine/machine.h" -#include "io.h" +#include "cpu.h" +#include "machine.h" +#include "86box_io.h" #include "pci.h" #include "pic.h" #include "timer.h" diff --git a/src/pic.d b/src/pic.d new file mode 100644 index 000000000..09037a99e --- /dev/null +++ b/src/pic.d @@ -0,0 +1,2 @@ +pic.o: pic.c 86box.h cpu_common/cpu.h machine/machine.h 86box_io.h pci.h \ + pic.h timer.h pit.h diff --git a/src/piix.h b/src/piix.h index 6de1d65b3..ff374439c 100644 --- a/src/piix.h +++ b/src/piix.h @@ -8,14 +8,15 @@ * * Emulation core dispatcher. * - * Version: @(#)piix.h 1.0.3 2018/05/11 + * Version: @(#)piix.h 1.0.4 2020/01/24 * * Authors: Sarah Walker, * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. */ extern const device_t piix_device; extern const device_t piix_pb640_device; extern const device_t piix3_device; +extern const device_t piix4_device; diff --git a/src/pit.c b/src/pit.c index eaab7a4e3..f3421a8f4 100644 --- a/src/pit.c +++ b/src/pit.c @@ -24,11 +24,11 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cpu/cpu.h" +#include "cpu.h" #include "device.h" #include "timer.h" #include "dma.h" -#include "io.h" +#include "86box_io.h" #include "nmi.h" #include "pic.h" #include "timer.h" @@ -43,7 +43,8 @@ pit_t *pit, *pit2; double cpuclock, PITCONSTD, SYSCLK, - isa_timing, bus_timing; + isa_timing, + bus_timing, pci_timing; uint64_t PITCONST, ISACONST, CGACONST, @@ -1024,7 +1025,9 @@ pit_set_clock(int clock) TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32)); isa_timing = (cpuclock / (double)8000000.0); + bus_timing = (cpuclock / (double)cpu_busspeed); + pci_timing = (cpuclock / (double)cpu_pci_speed); if (cpu_busspeed >= 30000000) SYSCLK = bus_timing * 4.0; diff --git a/src/pit.d b/src/pit.d new file mode 100644 index 000000000..249fa8f9e --- /dev/null +++ b/src/pit.d @@ -0,0 +1,3 @@ +pit.o: pit.c 86box.h cpu_common/cpu.h device.h timer.h dma.h 86box_io.h \ + nmi.h pic.h pit.h ppi.h machine/machine.h sound/sound.h \ + sound/snd_speaker.h video/video.h diff --git a/src/png.d b/src/png.d new file mode 100644 index 000000000..7bde88190 --- /dev/null +++ b/src/png.d @@ -0,0 +1,4 @@ +png.o: printer/png.c C:/msys64_gcc91/mingw32/include/libpng16/png.h \ + C:/msys64_gcc91/mingw32/include/libpng16/pnglibconf.h \ + C:/msys64_gcc91/mingw32/include/libpng16/pngconf.h 86box.h plat.h \ + lang/language.h plat_dynld.h ui.h video/video.h printer/png_struct.h diff --git a/src/port_92.c b/src/port_92.c index 1c5f1b2bf..7230111f2 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -22,13 +22,9 @@ #include #include "86box.h" #include "device.h" -#ifdef USE_NEW_DYNAREC -#include "cpu_new/cpu.h" -#else -#include "cpu/cpu.h" -#endif +#include "cpu.h" #include "timer.h" -#include "io.h" +#include "86box_io.h" #include "keyboard.h" #include "mem.h" #include "pit.h" diff --git a/src/port_92.d b/src/port_92.d new file mode 100644 index 000000000..0276df44a --- /dev/null +++ b/src/port_92.d @@ -0,0 +1,2 @@ +port_92.o: port_92.c 86box.h device.h cpu_common/cpu.h timer.h 86box_io.h \ + keyboard.h mem.h pit.h port_92.h diff --git a/src/pot.d b/src/pot.d new file mode 100644 index 000000000..db5171998 --- /dev/null +++ b/src/pot.d @@ -0,0 +1,2 @@ +pot.o: sound/resid-fp/pot.cc sound/resid-fp/pot.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/ppi.d b/src/ppi.d new file mode 100644 index 000000000..e185fc379 --- /dev/null +++ b/src/ppi.d @@ -0,0 +1 @@ +ppi.o: ppi.c timer.h cpu_common/cpu.h pit.h ppi.h diff --git a/src/printer/png.c b/src/printer/png.c index 752df0080..7d4555bd2 100644 --- a/src/printer/png.c +++ b/src/printer/png.c @@ -52,11 +52,11 @@ #include #define PNG_DEBUG 0 #include -#include "../86box.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" -#include "../video/video.h" +#include "86box.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" +#include "video.h" #include "png_struct.h" #ifdef _WIN32 diff --git a/src/printer/prt_cpmap.c b/src/printer/prt_cpmap.c index f7c7330f6..8713d0809 100644 --- a/src/printer/prt_cpmap.c +++ b/src/printer/prt_cpmap.c @@ -53,8 +53,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "printer.h" diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index c74449ba6..c965285ab 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -56,18 +56,18 @@ #include #include #include FT_FREETYPE_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../pit.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" -#include "../lpt.h" -#include "../video/video.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "pit.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" +#include "lpt.h" +#include "video.h" #include "png_struct.h" #include "printer.h" #include "prt_devs.h" diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 92ce3d83c..22d5f85b8 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -22,14 +22,14 @@ #include #include #include -#include "../86box.h" -#include "../lang/language.h" -#include "../lpt.h" -#include "../timer.h" -#include "../pit.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" +#include "86box.h" +#include "language.h" +#include "lpt.h" +#include "timer.h" +#include "pit.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" #include "prt_devs.h" #if defined(_WIN32) && !defined(__WINDOWS__) diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index 404e27c86..9219221f1 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -56,12 +56,12 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../pit.h" -#include "../plat.h" -#include "../lpt.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "pit.h" +#include "plat.h" +#include "lpt.h" #include "printer.h" #include "prt_devs.h" diff --git a/src/prt_cpmap.d b/src/prt_cpmap.d new file mode 100644 index 000000000..22f076bde --- /dev/null +++ b/src/prt_cpmap.d @@ -0,0 +1,2 @@ +prt_cpmap.o: printer/prt_cpmap.c 86box.h plat.h lang/language.h \ + printer/printer.h diff --git a/src/prt_escp.d b/src/prt_escp.d new file mode 100644 index 000000000..b1669dc12 --- /dev/null +++ b/src/prt_escp.d @@ -0,0 +1,16 @@ +prt_escp.o: printer/prt_escp.c \ + C:/msys64_gcc91/mingw32/include/freetype2/ft2build.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/config/ftheader.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/freetype.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/config/ftconfig.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/config/ftoption.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/config/ftstdlib.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/fttypes.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/ftsystem.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/ftimage.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/fterrors.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/ftmoderr.h \ + C:/msys64_gcc91/mingw32/include/freetype2/freetype/fterrdef.h 86box.h \ + cpu_common/cpu.h machine/machine.h timer.h mem.h rom.h pit.h plat.h \ + lang/language.h plat_dynld.h ui.h lpt.h video/video.h \ + printer/png_struct.h printer/printer.h printer/prt_devs.h diff --git a/src/prt_ps.d b/src/prt_ps.d new file mode 100644 index 000000000..77e76064f --- /dev/null +++ b/src/prt_ps.d @@ -0,0 +1,3 @@ +prt_ps.o: printer/prt_ps.c 86box.h lang/language.h lpt.h timer.h \ + cpu_common/cpu.h pit.h plat.h lang/language.h plat_dynld.h ui.h \ + printer/prt_devs.h diff --git a/src/prt_text.d b/src/prt_text.d new file mode 100644 index 000000000..81386becb --- /dev/null +++ b/src/prt_text.d @@ -0,0 +1,2 @@ +prt_text.o: printer/prt_text.c 86box.h device.h timer.h cpu_common/cpu.h \ + pit.h plat.h lang/language.h lpt.h printer/printer.h printer/prt_devs.h diff --git a/src/queue.d b/src/queue.d new file mode 100644 index 000000000..223ac18e9 --- /dev/null +++ b/src/queue.d @@ -0,0 +1 @@ +queue.o: network/slirp/queue.c network/slirp/queue.h diff --git a/src/random.d b/src/random.d new file mode 100644 index 000000000..66b2ab33c --- /dev/null +++ b/src/random.d @@ -0,0 +1 @@ +random.o: random.c random.h diff --git a/src/rom.c b/src/rom.c index 8d8c23e99..174ca0479 100644 --- a/src/rom.c +++ b/src/rom.c @@ -33,8 +33,8 @@ #include "mem.h" #include "rom.h" #include "plat.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" +#include "machine.h" +#include "m_xt_xi8088.h" #ifdef ENABLE_ROM_LOG diff --git a/src/rom.d b/src/rom.d new file mode 100644 index 000000000..11b5f4850 --- /dev/null +++ b/src/rom.d @@ -0,0 +1,2 @@ +rom.o: rom.c 86box.h mem.h rom.h plat.h lang/language.h machine/machine.h \ + machine/m_xt_xi8088.h machine/../device.h diff --git a/src/sbuf.d b/src/sbuf.d new file mode 100644 index 000000000..8954ce4fa --- /dev/null +++ b/src/sbuf.d @@ -0,0 +1,8 @@ +sbuf.o: network/slirp/sbuf.c network/slirp/slirp.h network/slirp/config.h \ + network/slirp/config-host.h network/slirp/slirp_config.h \ + network/slirp/debug.h network/slirp/ip.h network/slirp/tcp.h \ + network/slirp/tcp_var.h network/slirp/tcpip.h network/slirp/tcp_timer.h \ + network/slirp/udp.h network/slirp/icmp_var.h network/slirp/mbuf.h \ + network/slirp/sbuf.h network/slirp/socket.h network/slirp/if.h \ + network/slirp/main.h network/slirp/misc.h network/slirp/ctl.h \ + network/slirp/bootp.h network/slirp/tftp.h network/slirp/libslirp.h diff --git a/src/scamp.d b/src/scamp.d new file mode 100644 index 000000000..3456715e9 --- /dev/null +++ b/src/scamp.d @@ -0,0 +1,2 @@ +scamp.o: chipset/scamp.c 86box.h cpu_common/cpu.h timer.h device.h \ + 86box_io.h mem.h nmi.h port_92.h chipset/chipset.h diff --git a/src/scat.d b/src/scat.d new file mode 100644 index 000000000..50c8fc11d --- /dev/null +++ b/src/scat.d @@ -0,0 +1,3 @@ +scat.o: chipset/scat.c 86box.h device.h cpu_common/cpu.h cpu_common/x86.h \ + timer.h floppy/fdd.h floppy/fdc.h keyboard.h 86box_io.h mem.h nmi.h \ + port_92.h rom.h chipset/chipset.h diff --git a/src/scsi.d b/src/scsi.d new file mode 100644 index 000000000..5de04d448 --- /dev/null +++ b/src/scsi.d @@ -0,0 +1,4 @@ +scsi.o: scsi/scsi.c 86box.h device.h disk/hdc.h disk/hdd.h plat.h \ + lang/language.h scsi/scsi.h scsi/scsi_device.h cdrom/cdrom.h disk/zip.h \ + scsi/scsi_disk.h scsi/scsi_aha154x.h scsi/scsi_buslogic.h \ + scsi/scsi_ncr5380.h scsi/scsi_ncr53c8xx.h diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index c23e7f83d..faa7f108d 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -24,15 +24,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../disk/hdc.h" -#include "../disk/hdd.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "hdc.h" +#include "hdd.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" +#include "cdrom.h" +#include "zip.h" #include "scsi_disk.h" #include "scsi_aha154x.h" #include "scsi_buslogic.h" diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index ef7921a35..b3ec5f4a9 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -24,19 +24,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../mem.h" -#include "../mca.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../dma.h" -#include "../pic.h" -#include "../plat.h" -// #include "../cpu/cpu.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "mem.h" +#include "mca.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "dma.h" +#include "pic.h" +#include "plat.h" #include "scsi.h" #include "scsi_aha154x.h" #include "scsi_x54x.h" diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 28ecdb612..48d19c9f5 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -27,19 +27,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../mem.h" -#include "../mca.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../dma.h" -#include "../pic.h" -#include "../pci.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "mem.h" +#include "mca.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "dma.h" +#include "pic.h" +#include "pci.h" +#include "plat.h" #include "scsi.h" #include "scsi_buslogic.h" #include "scsi_device.h" diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 2f87dac04..ccb936901 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -23,19 +23,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../timer.h" -#include "../device.h" -#include "../piix.h" -#include "../scsi/scsi_device.h" -#include "../nvr.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../sound/sound.h" -#include "../plat.h" -#include "../ui.h" -#include "../cdrom/cdrom.h" +#include "86box.h" +#include "config.h" +#include "timer.h" +#include "device.h" +#include "piix.h" +#include "scsi_device.h" +#include "nvr.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "sound.h" +#include "plat.h" +#include "ui.h" +#include "cdrom.h" #include "scsi_cdrom.h" diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index c0fe14694..61aca0b81 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -20,9 +20,9 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../disk/hdd.h" +#include "86box.h" +#include "device.h" +#include "hdd.h" #include "scsi.h" #include "scsi_device.h" diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 61ee5c43f..a8fcc73bc 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -19,17 +19,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../device.h" -#include "../nvr.h" -#include "../piix.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" +#include "86box.h" +#include "timer.h" +#include "device.h" +#include "nvr.h" +#include "piix.h" +#include "hdd.h" +#include "hdc.h" #include "scsi_device.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" -#include "../ui.h" +#include "hdc_ide.h" +#include "plat.h" +#include "ui.h" #include "scsi_disk.h" diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index c361c2d14..9a652e8e1 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -27,17 +27,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_ncr5380.h" diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 56af023a1..3161e8f7f 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -32,17 +32,17 @@ #include #define HAVE_STDARG_H #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../mem.h" -#include "../rom.h" -#include "../pci.h" -#include "../device.h" -#include "../nvr.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "mem.h" +#include "rom.h" +#include "pci.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_ncr53c8xx.h" diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 8c8a5985d..f41d013a0 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -28,18 +28,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../pci.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../nvr.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "pci.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "nvr.h" +#include "plat.h" #include "scsi.h" #include "scsi_device.h" #include "scsi_aha154x.h" diff --git a/src/scsi_aha154x.d b/src/scsi_aha154x.d new file mode 100644 index 000000000..029995328 --- /dev/null +++ b/src/scsi_aha154x.d @@ -0,0 +1,3 @@ +scsi_aha154x.o: scsi/scsi_aha154x.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mca.h mem.h rom.h device.h nvr.h dma.h pic.h plat.h \ + lang/language.h scsi/scsi.h scsi/scsi_aha154x.h scsi/scsi_x54x.h diff --git a/src/scsi_buslogic.d b/src/scsi_buslogic.d new file mode 100644 index 000000000..885e0500c --- /dev/null +++ b/src/scsi_buslogic.d @@ -0,0 +1,4 @@ +scsi_buslogic.o: scsi/scsi_buslogic.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mca.h mem.h rom.h device.h nvr.h dma.h pic.h pci.h \ + plat.h lang/language.h scsi/scsi.h scsi/scsi_buslogic.h \ + scsi/scsi_device.h scsi/scsi_x54x.h diff --git a/src/scsi_cdrom.d b/src/scsi_cdrom.d new file mode 100644 index 000000000..394cd5322 --- /dev/null +++ b/src/scsi_cdrom.d @@ -0,0 +1,4 @@ +scsi_cdrom.o: scsi/scsi_cdrom.c 86box.h config.h timer.h cpu_common/cpu.h \ + device.h piix.h scsi/scsi_device.h nvr.h disk/hdc.h disk/hdc_ide.h \ + sound/sound.h plat.h lang/language.h ui.h cdrom/cdrom.h \ + scsi/scsi_cdrom.h diff --git a/src/scsi_device.d b/src/scsi_device.d new file mode 100644 index 000000000..fcc7628be --- /dev/null +++ b/src/scsi_device.d @@ -0,0 +1,2 @@ +scsi_device.o: scsi/scsi_device.c 86box.h device.h disk/hdd.h scsi/scsi.h \ + scsi/scsi_device.h diff --git a/src/scsi_disk.d b/src/scsi_disk.d new file mode 100644 index 000000000..5559b10d0 --- /dev/null +++ b/src/scsi_disk.d @@ -0,0 +1,3 @@ +scsi_disk.o: scsi/scsi_disk.c 86box.h timer.h cpu_common/cpu.h device.h \ + nvr.h piix.h disk/hdd.h disk/hdc.h scsi/scsi_device.h disk/hdc_ide.h \ + plat.h lang/language.h ui.h scsi/scsi_disk.h diff --git a/src/scsi_ncr5380.d b/src/scsi_ncr5380.d new file mode 100644 index 000000000..24ef41de8 --- /dev/null +++ b/src/scsi_ncr5380.d @@ -0,0 +1,3 @@ +scsi_ncr5380.o: scsi/scsi_ncr5380.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h dma.h pic.h mca.h mem.h rom.h device.h nvr.h plat.h \ + lang/language.h scsi/scsi.h scsi/scsi_device.h scsi/scsi_ncr5380.h diff --git a/src/scsi_ncr53c8xx.d b/src/scsi_ncr53c8xx.d new file mode 100644 index 000000000..2cebdb7e9 --- /dev/null +++ b/src/scsi_ncr53c8xx.d @@ -0,0 +1,3 @@ +scsi_ncr53c8xx.o: scsi/scsi_ncr53c8xx.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h dma.h pic.h mem.h rom.h pci.h device.h nvr.h plat.h \ + lang/language.h scsi/scsi.h scsi/scsi_device.h scsi/scsi_ncr53c8xx.h diff --git a/src/scsi_x54x.d b/src/scsi_x54x.d new file mode 100644 index 000000000..019ed87aa --- /dev/null +++ b/src/scsi_x54x.d @@ -0,0 +1,4 @@ +scsi_x54x.o: scsi/scsi_x54x.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + dma.h pic.h pci.h mca.h mem.h rom.h device.h nvr.h plat.h \ + lang/language.h scsi/scsi.h scsi/scsi_device.h scsi/scsi_aha154x.h \ + scsi/scsi_x54x.h diff --git a/src/serial.c b/src/serial.c index 51297a64b..7d35466a7 100644 --- a/src/serial.c +++ b/src/serial.c @@ -10,15 +10,15 @@ * * Now passes all the AMIDIAG tests. * - * Version: @(#)serial.h 1.0.13 2019/10/31 + * Version: @(#)serial.h 1.0.14 2020/01/24 * * Author: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #include #include @@ -30,8 +30,8 @@ #include "86box.h" #include "device.h" #include "timer.h" -#include "machine/machine.h" -#include "io.h" +#include "machine.h" +#include "86box_io.h" #include "pic.h" #include "mem.h" #include "rom.h" @@ -95,7 +95,7 @@ serial_transmit_period(serial_t *dev) ddlab = (double) dev->dlab; /* Bit period based on DLAB. */ - dev->transmit_period = (16000000.0 * ddlab) / 1843200.0; + dev->transmit_period = (16000000.0 * ddlab) / dev->clock_src; } @@ -337,6 +337,16 @@ serial_reset_fifo(serial_t *dev) } +void +serial_set_clock_src(serial_t *dev, double clock_src) +{ + dev->clock_src = clock_src; + + serial_transmit_period(dev); + serial_update_speed(dev); +} + + void serial_write(uint16_t addr, uint8_t val, void *p) { @@ -676,6 +686,7 @@ serial_init(const device_t *info) /* Default to 1200,N,7. */ dev->dlab = 96; dev->fcr = 0x06; + dev->clock_src = 1843200.0; serial_transmit_period(dev); timer_add(&dev->transmit_timer, serial_transmit_timer, dev, 0); timer_add(&dev->timeout_timer, serial_timeout_timer, dev, 0); diff --git a/src/serial.d b/src/serial.d new file mode 100644 index 000000000..f703b28aa --- /dev/null +++ b/src/serial.d @@ -0,0 +1,2 @@ +serial.o: serial.c 86box.h device.h timer.h cpu_common/cpu.h \ + machine/machine.h 86box_io.h pic.h mem.h rom.h serial.h mouse.h diff --git a/src/serial.h b/src/serial.h index 73238c87b..7ec03dc66 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,15 +8,15 @@ * * Definitions for the NS8250/16450/16550 UART emulation. * - * Version: @(#)serial.h 1.0.12 2019/10/31 + * Version: @(#)serial.h 1.0.13 2020/01/24 * * Author: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_SERIAL_H # define EMU_SERIAL_H @@ -53,7 +53,7 @@ typedef struct serial_s rcvr_fifo[16], xmit_fifo[16]; pc_timer_t transmit_timer, timeout_timer; - double transmit_period; + double clock_src, transmit_period; struct serial_device_s *sd; } serial_t; @@ -78,6 +78,7 @@ extern void serial_clear_fifo(serial_t *dev); extern void serial_write_fifo(serial_t *dev, uint8_t dat); extern void serial_set_next_inst(int ni); extern void serial_standalone_init(void); +extern void serial_set_clock_src(serial_t *dev, double clock_src); extern const device_t i8250_device; extern const device_t i8250_pcjr_device; diff --git a/src/sha1.d b/src/sha1.d new file mode 100644 index 000000000..497b84115 --- /dev/null +++ b/src/sha1.d @@ -0,0 +1 @@ +sha1.o: sound/munt/sha1/sha1.cpp sound/munt/sha1/sha1.h diff --git a/src/sid.d b/src/sid.d new file mode 100644 index 000000000..7cc4b8a57 --- /dev/null +++ b/src/sid.d @@ -0,0 +1,4 @@ +sid.o: sound/resid-fp/sid.cc sound/resid-fp/sid.h \ + sound/resid-fp/siddefs-fp.h sound/resid-fp/voice.h sound/resid-fp/wave.h \ + sound/resid-fp/envelope.h sound/resid-fp/filter.h \ + sound/resid-fp/extfilt.h sound/resid-fp/pot.h diff --git a/src/sio.h b/src/sio.h index 76f3a08f1..fc6c2bd61 100644 --- a/src/sio.h +++ b/src/sio.h @@ -8,10 +8,10 @@ * * Definitions for the Super I/O chips. * - * Version: @(#)sio.h 1.0.6 2019/05/17 + * Version: @(#)sio.h 1.0.7 2020/01/25 * * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_SIO_H # define EMU_SIO_H @@ -28,9 +28,13 @@ extern const device_t fdc37c935_device; extern const device_t pc87306_device; extern const device_t sio_detect_device; extern const device_t um8669f_device; +extern const device_t w83787f_device; extern const device_t w83877f_device; extern const device_t w83877f_president_device; extern const device_t w83877tf_device; +extern const device_t w83877tf_acorp_device; +extern const device_t w83977f_device; +extern const device_t w83977tf_device; #endif /*EMU_SIO_H*/ diff --git a/src/sio_acc3221.c b/src/sio_acc3221.c index 18f759f17..93de9cb0a 100644 --- a/src/sio_acc3221.c +++ b/src/sio_acc3221.c @@ -20,16 +20,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" typedef struct acc3221_t diff --git a/src/sio_acc3221.d b/src/sio_acc3221.d new file mode 100644 index 000000000..d1d4bf9bc --- /dev/null +++ b/src/sio_acc3221.d @@ -0,0 +1,3 @@ +sio_acc3221.o: sio_acc3221.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + device.h pci.h lpt.h serial.h disk/hdc.h disk/hdc_ide.h floppy/fdd.h \ + floppy/fdc.h sio.h diff --git a/src/sio_detect.c b/src/sio_detect.c index bc0a3e377..189ef3caf 100644 --- a/src/sio_detect.c +++ b/src/sio_detect.c @@ -21,10 +21,10 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c669.c b/src/sio_fdc37c669.c index 1f484af41..1bee36e59 100644 --- a/src/sio_fdc37c669.c +++ b/src/sio_fdc37c669.c @@ -19,16 +19,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c669.d b/src/sio_fdc37c669.d new file mode 100644 index 000000000..5561bcb57 --- /dev/null +++ b/src/sio_fdc37c669.d @@ -0,0 +1,3 @@ +sio_fdc37c669.o: sio_fdc37c669.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h device.h pci.h lpt.h serial.h disk/hdc.h disk/hdc_ide.h \ + floppy/fdd.h floppy/fdc.h sio.h diff --git a/src/sio_fdc37c66x.c b/src/sio_fdc37c66x.c index c1560f920..78d49c991 100644 --- a/src/sio_fdc37c66x.c +++ b/src/sio_fdc37c66x.c @@ -23,16 +23,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c66x.d b/src/sio_fdc37c66x.d new file mode 100644 index 000000000..cc14249bf --- /dev/null +++ b/src/sio_fdc37c66x.d @@ -0,0 +1,3 @@ +sio_fdc37c66x.o: sio_fdc37c66x.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h device.h pci.h lpt.h serial.h disk/hdc.h disk/hdc_ide.h \ + floppy/fdd.h floppy/fdc.h sio.h diff --git a/src/sio_fdc37c67x.c b/src/sio_fdc37c67x.c new file mode 100644 index 000000000..3560f8fde --- /dev/null +++ b/src/sio_fdc37c67x.c @@ -0,0 +1,519 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83977F Super I/O Chip. + * + * Winbond W83977F Super I/O Chip + * Used by the Award 430TX + * + * Version: @(#)sio_w83977f.c 1.0.0 2020/01/24 + * + * Author: Miran Grca, + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define HEFRAS (dev->regs[0x26] & 0x40) + + +typedef struct { + uint8_t tries, regs[48], + dev_regs[256][208]; + int locked, rw_locked, + cur_reg, base_address, + type; + fdc_t *fdc; + serial_t *uart[2]; +} w83977f_t; + + +static void w83977f_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83977f_read(uint16_t port, void *priv); + + +static void +w83977f_remap(w83977f_t *dev) +{ + io_removehandler(0x3f0, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + io_removehandler(0x370, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + + dev->base_address = (HEFRAS ? 0x370 : 0x3f0); + + io_sethandler(dev->base_address, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); +} + + +static uint8_t +get_lpt_length(w83977f_t *dev) +{ + uint8_t length = 4; + + if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) && + ((dev->dev_regs[1][0xc0] & 0x07) != 0x04)) + length = 8; + + return length; +} + + +static void +w83977f_fdc_handler(w83977f_t *dev) +{ + uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31]; + + fdc_remove(dev->fdc); + + pclog("fdc: %02X %02X %04X\n", dev->dev_regs[0][0x00], dev->regs[0x22], io_base); + if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8)) + fdc_set_base(dev->fdc, io_base); + + fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f); +} + + +static void +w83977f_lpt_handler(w83977f_t *dev) +{ + uint16_t io_mask, io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31]; + int io_len = get_lpt_length(dev); + io_base &= (0xfff & ~io_len); + io_mask = 0xffc; + if (io_len == 8) + io_mask = 0xff8; + + lpt1_remove(); + + if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) + lpt1_init(io_base); + + lpt1_irq(dev->dev_regs[1][0x40] & 0x0f); +} + + +static void +w83977f_serial_handler(w83977f_t *dev, int uart) +{ + uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31]; + double clock_src = 24000000.0 / 13.0; + + serial_remove(dev->uart[uart]); + + if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8)) + serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f); + + switch (dev->dev_regs[2 + uart][0xc0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); +} + + +static void +w83977f_write(uint16_t port, uint8_t val, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0; + uint8_t ld = dev->regs[7]; + + // pclog("W83977F Write: %04X %02X\n", port, val); + + if (index) { + if ((val == 0x87) && !dev->locked) { + if (dev->tries) { + dev->locked = 1; + dev->tries = 0; + } else + dev->tries++; + } else { + if (dev->locked) { + if (val == 0xaa) + dev->locked = 0; + else + dev->cur_reg = val; + } else { + if (dev->tries) + dev->tries = 0; + } + } + return; + } else { + if (dev->locked) { + if (dev->rw_locked) + return; + if (dev->cur_reg >= 0x30) { + valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30]; + dev->dev_regs[ld][dev->cur_reg - 0x30] = val; + } else { + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } + } else + return; + } + + switch (dev->cur_reg) { + case 0x02: + if (valxor & 0x02) + softresetx86(); + break; + case 0x22: + if (valxor & 0x20) + w83977f_serial_handler(dev, 1); + if (valxor & 0x10) + w83977f_serial_handler(dev, 0); + if (valxor & 0x08) + w83977f_lpt_handler(dev); + if (valxor & 0x01) + w83977f_fdc_handler(dev); + break; + case 0x26: + if (valxor & 0x20) + dev->rw_locked = (val & 0x20) ? 1 : 0; + case 0x30: + if (valxor & 0x01) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x60: case 0x61: + if (valxor & 0xff) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x70: + if (valxor & 0x0f) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf0: + switch (ld) { + case 0x00: + if (valxor & 0x20) + fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0); + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0); + break; + case 0x01: + if (valxor & 0x07) + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + if (valxor & 0x03) + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf1: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6); + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2); + if (valxor & 0x02) + fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0); + if (valxor & 0x01) + fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); + break; + } + break; + case 0xf2: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, val & 0x03); + break; + } + break; + case 0xf4: case 0xf5: case 0xf6: case 0xf7: + switch (ld) { + case 0x00: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); + break; + } + break; + } +} + + +static uint8_t +w83977f_read(uint16_t port, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t ret = 0xff; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ld = dev->regs[7]; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (!dev->rw_locked) { + if ((dev->cur_reg == 0xf2) && (ld == 0x00)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if (dev->cur_reg >= 0x30) + ret = dev->dev_regs[ld][dev->cur_reg - 0x30]; + else + ret = dev->regs[dev->cur_reg]; + } + } + } + + // pclog("W83977F Read: %04X %02X\n", port, ret); + + return ret; +} + + +static void +w83977f_reset(w83977f_t *dev) +{ + int i; + + memset(dev->regs, 0, 48); + for (i = 0; i < 256; i++) + memset(dev->dev_regs[i], 0, 208); + + dev->regs[0x20] = 0x97; + dev->regs[0x21] = dev->type ? 0x73 : 0x71; + dev->regs[0x22] = 0xff; + dev->regs[0x24] = dev->type ? 0x84 : 0xa4; + + /* WARNING: Array elements are register - 0x30. */ + /* Logical Device 0 (FDC) */ + dev->dev_regs[0][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[0][0x01] = 0x02; + dev->dev_regs[0][0x30] = 0x03; dev->dev_regs[0][0x31] = 0xf0; + dev->dev_regs[0][0x40] = 0x06; + if (!dev->type) + dev->dev_regs[0][0x41] = 0x02; /* Read-only */ + dev->dev_regs[0][0x44] = 0x02; + dev->dev_regs[0][0xc0] = 0x0e; + + /* Logical Device 1 (Parallel Port) */ + dev->dev_regs[1][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[1][0x01] = 0x02; + dev->dev_regs[1][0x30] = 0x03; dev->dev_regs[1][0x31] = 0x78; + dev->dev_regs[1][0x40] = 0x07; + if (!dev->type) + dev->dev_regs[1][0x41] = 0x02; /* Read-only */ + dev->dev_regs[1][0x44] = 0x04; + dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is priner mode. */ + + /* Logical Device 2 (UART A) */ + dev->dev_regs[2][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[2][0x01] = 0x02; + dev->dev_regs[2][0x30] = 0x03; dev->dev_regs[2][0x31] = 0xf8; + dev->dev_regs[2][0x40] = 0x04; + if (!dev->type) + dev->dev_regs[2][0x41] = 0x02; /* Read-only */ + + /* Logical Device 3 (UART B) */ + dev->dev_regs[3][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[3][0x01] = 0x02; + dev->dev_regs[3][0x30] = 0x02; dev->dev_regs[3][0x31] = 0xf8; + dev->dev_regs[3][0x40] = 0x03; + if (!dev->type) + dev->dev_regs[3][0x41] = 0x02; /* Read-only */ + + /* Logical Device 4 (RTC) */ + if (!dev->type) { + dev->dev_regs[4][0x00] = 0x01; + dev->dev_regs[4][0x01] = 0x02; + dev->dev_regs[4][0x30] = 0x00; dev->dev_regs[4][0x31] = 0x70; + dev->dev_regs[4][0x40] = 0x08; + dev->dev_regs[4][0x41] = 0x02; /* Read-only */ + } + + /* Logical Device 5 (KBC) */ + dev->dev_regs[5][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x01] = 0x02; + dev->dev_regs[5][0x30] = 0x00; dev->dev_regs[5][0x31] = 0x60; + dev->dev_regs[5][0x40] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x41] = 0x02; /* Read-only */ + dev->dev_regs[5][0x42] = 0x0c; + if (!dev->type) + dev->dev_regs[5][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40; + + /* Logical Device 6 (IR) = UART C */ + if (!dev->type) { + dev->dev_regs[6][0x01] = 0x02; + dev->dev_regs[6][0x41] = 0x02; /* Read-only */ + dev->dev_regs[6][0x44] = 0x04; + dev->dev_regs[6][0x45] = 0x04; + } + + /* Logical Device 7 (Auxiliary I/O Part I) */ + if (!dev->type) + dev->dev_regs[7][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[7][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[7][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; + if (dev->type) + dev->dev_regs[7][0xb7] = 0x01; + + /* Logical Device 8 (Auxiliary I/O Part II) */ + if (!dev->type) + dev->dev_regs[8][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[8][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[8][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[8][0xb8] = 0x01; dev->dev_regs[8][0xb9] = 0x01; + dev->dev_regs[8][0xba] = 0x01; dev->dev_regs[8][0xbb] = 0x01; + dev->dev_regs[8][0xbc] = 0x01; dev->dev_regs[8][0xbd] = 0x01; + dev->dev_regs[8][0xbe] = 0x01; dev->dev_regs[8][0xbf] = 0x01; + + /* Logical Device 9 (Auxiliary I/O Part III) */ + if (dev->type) { + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; dev->dev_regs[7][0xb7] = 0x01; + } + + fdc_reset(dev->fdc); + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + w83977f_fdc_handler(dev); + w83977f_lpt_handler(dev); + w83977f_serial_handler(dev, 0); + w83977f_serial_handler(dev, 1); + + w83977f_remap(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + + +static void +w83977f_close(void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + + free(dev); +} + + +static void * +w83977f_init(const device_t *info) +{ + w83977f_t *dev = (w83977f_t *) malloc(sizeof(w83977f_t)); + memset(dev, 0, sizeof(w83977f_t)); + + dev->type = info->local; + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + w83977f_reset(dev); + + return dev; +} + + +const device_t w83977f_device = { + "Winbond W83977F Super I/O", + 0, + 0, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t w83977tf_device = { + "Winbond W83977TF Super I/O", + 0, + 1, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_fdc37c93x.c b/src/sio_fdc37c93x.c index ef3380ee4..f34bc7e8e 100644 --- a/src/sio_fdc37c93x.c +++ b/src/sio_fdc37c93x.c @@ -20,16 +20,16 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" diff --git a/src/sio_fdc37c93x.d b/src/sio_fdc37c93x.d new file mode 100644 index 000000000..898433012 --- /dev/null +++ b/src/sio_fdc37c93x.d @@ -0,0 +1,3 @@ +sio_fdc37c93x.o: sio_fdc37c93x.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h device.h pci.h lpt.h serial.h disk/hdc.h disk/hdc_ide.h \ + floppy/fdd.h floppy/fdc.h sio.h diff --git a/src/sio_pc87306.c b/src/sio_pc87306.c index c2d3ceaf8..7b9a733b6 100644 --- a/src/sio_pc87306.c +++ b/src/sio_pc87306.c @@ -19,18 +19,19 @@ #include #include #include "86box.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "device.h" #include "lpt.h" #include "mem.h" +#include "nvr.h" #include "pci.h" #include "rom.h" #include "serial.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" @@ -40,6 +41,7 @@ typedef struct { int cur_reg; fdc_t *fdc; serial_t *uart[2]; + nvr_t *nvr; } pc87306_t; @@ -287,6 +289,14 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } } break; + case 4: + // pclog("NVR RAM mask set to %i\n", !!(val & 0x80)); + break; + case 5: + // pclog("Reserved set to %i\n", !!(val & 0x04)); + // pclog("RTC is now %sabled\n", (val & 0x08) ? "en" : "dis"); + // pclog("NVR RAM bank set to %i\n", !!(val & 0x20)); + break; case 9: if (valxor & 0x44) { fdc_update_enh_mode(dev->fdc, (val & 4) ? 1 : 0); @@ -298,6 +308,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) pc87306_gpio_init(dev); break; case 0x12: + // pclog("NVR RAM 38-3F lock set to %i\n", !!(val & 0x01)); if (valxor & 0x30) pc87306_gpio_init(dev); break; @@ -406,6 +417,8 @@ pc87306_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + // dev->nvr = device_add(&piix4_nvr_device); + pc87306_reset(dev); io_sethandler(0x02e, 0x0002, diff --git a/src/sio_pc87306.d b/src/sio_pc87306.d new file mode 100644 index 000000000..e516fa530 --- /dev/null +++ b/src/sio_pc87306.d @@ -0,0 +1,3 @@ +sio_pc87306.o: sio_pc87306.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + device.h lpt.h mem.h nvr.h pci.h rom.h serial.h disk/hdc.h \ + disk/hdc_ide.h floppy/fdd.h floppy/fdc.h sio.h diff --git a/src/sio_um8669f - Cópia.c b/src/sio_um8669f - Cópia.c new file mode 100644 index 000000000..4e86b6b3c --- /dev/null +++ b/src/sio_um8669f - Cópia.c @@ -0,0 +1,321 @@ +/*um8669f : + + aa to 108 unlocks + next 108 write is register select (Cx?) + data read/write to 109 + 55 to 108 locks + +C1 +bit 7 - enable PnP registers + +PnP registers : + +07 - device : + 0 = FDC + 1 = COM1 + 2 = COM2 + 3 = LPT1 + 5 = Game port +30 - enable +60/61 - addr +70 - IRQ +74 - DMA*/ + +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define DEV_FDC 0 +#define DEV_COM1 1 +#define DEV_COM2 2 +#define DEV_LPT1 3 +#define DEV_GAME 5 + +#define REG_DEVICE 0x07 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 + + +typedef struct um8669f_t +{ + int locked, cur_reg_108, + cur_reg, cur_device, + pnp_active; + + uint8_t regs_108[256]; + + struct { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[8]; + + fdc_t *fdc; + serial_t *uart[2]; +} um8669f_t; + + +static void +um8669f_pnp_write(uint16_t port, uint8_t val, void *priv) +{ + um8669f_t *dev = (um8669f_t *) priv; + + uint8_t valxor = 0; + uint8_t lpt_irq = 0xff; + + if (port == 0x279) + dev->cur_reg = val; + else { + if (dev->cur_reg == REG_DEVICE) + dev->cur_device = val & 7; + else { + switch (dev->cur_reg) { + case REG_ENABLE: + valxor = dev->dev[dev->cur_device].enable ^ val; + dev->dev[dev->cur_device].enable = val; + break; + case REG_ADDRLO: + valxor = (dev->dev[dev->cur_device].addr & 0xff) ^ val; + dev->dev[dev->cur_device].addr = (dev->dev[dev->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + valxor = ((dev->dev[dev->cur_device].addr >> 8) & 0xff) ^ val; + dev->dev[dev->cur_device].addr = (dev->dev[dev->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + valxor = dev->dev[dev->cur_device].irq ^ val; + dev->dev[dev->cur_device].irq = val; + break; + case REG_DMA: + valxor = dev->dev[dev->cur_device].dma ^ val; + dev->dev[dev->cur_device].dma = val; + break; + default: + valxor = 0; + break; + } + + switch (dev->cur_device) { + case DEV_FDC: + if ((dev->cur_reg == REG_ENABLE) && valxor) { + fdc_remove(dev->fdc); + if (dev->dev[DEV_FDC].enable & 1) + fdc_set_base(dev->fdc, 0x03f0); + } + break; + case DEV_COM1: + if ((dev->cur_reg == REG_ENABLE) && valxor) { + serial_remove(dev->uart[0]); + if (dev->dev[DEV_COM1].enable & 1) + serial_setup(dev->uart[0], dev->dev[DEV_COM1].addr, dev->dev[DEV_COM1].irq); + } + break; + case DEV_COM2: + if ((dev->cur_reg == REG_ENABLE) && valxor) { + serial_remove(dev->uart[1]); + if (dev->dev[DEV_COM2].enable & 1) + serial_setup(dev->uart[1], dev->dev[DEV_COM2].addr, dev->dev[DEV_COM2].irq); + } + break; + case DEV_LPT1: + if ((dev->cur_reg == REG_ENABLE) && valxor) { + lpt1_remove(); + if (dev->dev[DEV_LPT1].enable & 1) + lpt1_init(dev->dev[DEV_LPT1].addr); + } + if (dev->dev[DEV_LPT1].irq <= 15) + lpt_irq = dev->dev[DEV_LPT1].irq; + lpt1_irq(lpt_irq); + break; + } + } + } +} + + +static uint8_t +um8669f_pnp_read(uint16_t port, void *priv) +{ + um8669f_t *dev = (um8669f_t *) priv; + uint8_t ret = 0xff; + + switch (dev->cur_reg) { + case REG_DEVICE: + ret = dev->cur_device; + break; + case REG_ENABLE: + ret = dev->dev[dev->cur_device].enable; + break; + case REG_ADDRLO: + ret = dev->dev[dev->cur_device].addr & 0xff; + break; + case REG_ADDRHI: + ret = dev->dev[dev->cur_device].addr >> 8; + break; + case REG_IRQ: + ret = dev->dev[dev->cur_device].irq; + break; + case REG_DMA: + ret = dev->dev[dev->cur_device].dma; + break; + } + + return ret; +} + + +void um8669f_write(uint16_t port, uint8_t val, void *priv) +{ + um8669f_t *dev = (um8669f_t *) priv; + int new_pnp_active; + + if (dev->locked) { + if ((port == 0x108) && (val == 0xaa)) + dev->locked = 0; + } else { + if (port == 0x108) { + if (val == 0x55) + dev->locked = 1; + else + dev->cur_reg_108 = val; + } else { + dev->regs_108[dev->cur_reg_108] = val; + + if (dev->cur_reg_108 == 0xc1) { + new_pnp_active = !!(dev->regs_108[0xc1] & 0x80); + if (new_pnp_active != dev->pnp_active) { + if (new_pnp_active) { + io_sethandler(0x0279, 0x0001, + NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, dev); + io_sethandler(0x0a79, 0x0001, + NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, dev); + io_sethandler(0x03e3, 0x0001, + um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, dev); + } else { + io_removehandler(0x0279, 0x0001, + NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, dev); + io_removehandler(0x0a79, 0x0001, + NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, dev); + io_removehandler(0x03e3, 0x0001, + um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, dev); + } + dev->pnp_active = new_pnp_active; + } + } + } + } +} + + +uint8_t um8669f_read(uint16_t port, void *priv) +{ + um8669f_t *dev = (um8669f_t *) priv; + uint8_t ret = 0xff; + + if (!dev->locked) { + if (port == 0x108) + ret = dev->cur_reg_108; /* ??? */ + else + ret = dev->regs_108[dev->cur_reg_108]; + } + + return ret; +} + + +void +um8669f_reset(um8669f_t *dev) +{ + fdc_reset(dev->fdc); + + serial_remove(dev->uart[0]); + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + + serial_remove(dev->uart[1]); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + lpt1_remove(); + lpt1_init(0x378); + + if (dev->pnp_active) { + io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, dev); + io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, dev); + io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, dev); + dev->pnp_active = 0; + } + + dev->locked = 1; + + dev->dev[DEV_FDC].enable = 1; + dev->dev[DEV_FDC].addr = 0x03f0; + dev->dev[DEV_FDC].irq = 6; + dev->dev[DEV_FDC].dma = 2; + + dev->dev[DEV_COM1].enable = 1; + dev->dev[DEV_COM1].addr = 0x03f8; + dev->dev[DEV_COM1].irq = 4; + + dev->dev[DEV_COM2].enable = 1; + dev->dev[DEV_COM2].addr = 0x02f8; + dev->dev[DEV_COM2].irq = 3; + + dev->dev[DEV_LPT1].enable = 1; + dev->dev[DEV_LPT1].addr = 0x0378; + dev->dev[DEV_LPT1].irq = 7; +} + + +static void +um8669f_close(void *priv) +{ + um8669f_t *dev = (um8669f_t *) priv; + + free(dev); +} + + +static void * +um8669f_init(const device_t *info) +{ + um8669f_t *dev = (um8669f_t *) malloc(sizeof(um8669f_t)); + memset(dev, 0, sizeof(um8669f_t)); + + dev->fdc = device_add(&fdc_at_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + io_sethandler(0x0108, 0x0002, + um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, dev); + + um8669f_reset(dev); + + return dev; +} + + +const device_t um8669f_device = { + "UMC UM8669F Super I/O", + 0, + 0, + um8669f_init, um8669f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_um8669f.c b/src/sio_um8669f.c index d946c251c..462dfa09b 100644 --- a/src/sio_um8669f.c +++ b/src/sio_um8669f.c @@ -28,13 +28,13 @@ PnP registers : #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "pci.h" #include "lpt.h" #include "serial.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" @@ -80,6 +80,8 @@ um8669f_pnp_write(uint16_t port, uint8_t val, void *priv) uint8_t valxor = 0; uint8_t lpt_irq = 0xff; + pclog("Write %02X at %04X\n", val, port); + if (port == 0x279) dev->cur_reg = val; else { @@ -181,11 +183,14 @@ um8669f_pnp_read(uint16_t port, void *priv) } -void um8669f_write(uint16_t port, uint8_t val, void *priv) +void +um8669f_write(uint16_t port, uint8_t val, void *priv) { um8669f_t *dev = (um8669f_t *) priv; int new_pnp_active; + pclog("Write %02X at %04X\n", val, port); + if (dev->locked) { if ((port == 0x108) && (val == 0xaa)) dev->locked = 0; @@ -224,7 +229,8 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) } -uint8_t um8669f_read(uint16_t port, void *priv) +uint8_t +um8669f_read(uint16_t port, void *priv) { um8669f_t *dev = (um8669f_t *) priv; uint8_t ret = 0xff; @@ -291,13 +297,27 @@ um8669f_close(void *priv) } +void +um8669f_detect_write(uint16_t port, uint8_t val, void *priv) +{ + pclog("Write %02X at %04X\n", val, port); +} + + +uint8_t +um8669f_detect_read(uint16_t port, void *priv) +{ + return 0xff; +} + + static void * um8669f_init(const device_t *info) { um8669f_t *dev = (um8669f_t *) malloc(sizeof(um8669f_t)); memset(dev, 0, sizeof(um8669f_t)); - dev->fdc = device_add(&fdc_at_device); + dev->fdc = device_add(&fdc_at_smc_device); dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); @@ -305,6 +325,15 @@ um8669f_init(const device_t *info) io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, dev); + io_sethandler(0x0370, 0x0002, + um8669f_detect_read, NULL, NULL, um8669f_detect_write, NULL, NULL, dev); + io_sethandler(0x03bd, 0x0001, + um8669f_detect_read, NULL, NULL, um8669f_detect_write, NULL, NULL, dev); + io_sethandler(0x03bf, 0x0001, + um8669f_detect_read, NULL, NULL, um8669f_detect_write, NULL, NULL, dev); + io_sethandler(0x03f0, 0x0002, + um8669f_detect_read, NULL, NULL, um8669f_detect_write, NULL, NULL, dev); + um8669f_reset(dev); return dev; diff --git a/src/sio_um8669f.d b/src/sio_um8669f.d new file mode 100644 index 000000000..355053b48 --- /dev/null +++ b/src/sio_um8669f.d @@ -0,0 +1,2 @@ +sio_um8669f.o: sio_um8669f.c 86box.h device.h 86box_io.h timer.h \ + cpu_common/cpu.h pci.h lpt.h serial.h floppy/fdd.h floppy/fdc.h sio.h diff --git a/src/sio_w83787f.c b/src/sio_w83787f.c new file mode 100644 index 000000000..df77b5062 --- /dev/null +++ b/src/sio_w83787f.c @@ -0,0 +1,387 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83787F/IF Super I/O Chip. + * + * Winbond W83787F Super I/O Chip + * Used by the Award 430HX + * + * Version: @(#)sio_w83787f.c 1.0.0 2020/01/11 + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define FDDA_TYPE (dev->regs[7] & 3) +#define FDDB_TYPE ((dev->regs[7] >> 2) & 3) +#define FDDC_TYPE ((dev->regs[7] >> 4) & 3) +#define FDDD_TYPE ((dev->regs[7] >> 6) & 3) + +#define FD_BOOT (dev->regs[8] & 3) +#define SWWP ((dev->regs[8] >> 4) & 1) +#define DISFDDWR ((dev->regs[8] >> 5) & 1) + +#define EN3MODE ((dev->regs[9] >> 5) & 1) + +#define DRV2EN_NEG (dev->regs[0xB] & 1) /* 0 = drive 2 installed */ +#define INVERTZ ((dev->regs[0xB] >> 1) & 1) /* 0 = invert DENSEL polarity */ +#define IDENT ((dev->regs[0xB] >> 3) & 1) + +#define HEFERE ((dev->regs[0xC] >> 5) & 1) + + +typedef struct { + uint8_t tries, regs[42]; + uint16_t reg_init; + int locked, rw_locked, + cur_reg, + key; + fdc_t *fdc; + serial_t *uart[2]; +} w83787f_t; + + +static void w83787f_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83787f_read(uint16_t port, void *priv); + + +static void +w83787f_remap(w83787f_t *dev) +{ + io_removehandler(0x250, 0x0003, + w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev); + io_sethandler(0x250, 0x0003, + w83787f_read, NULL, NULL, w83787f_write, NULL, NULL, dev); + dev->key = 0x88 | HEFERE; +} + + +#ifdef FIXME +/* FIXME: Implement EPP (and ECP) parallel port modes. */ +static uint8_t +get_lpt_length(w83787f_t *dev) +{ + uint8_t length = 4; + + if (dev->regs[9] & 0x80) { + if (dev->regs[0] & 0x04) + length = 8; /* EPP mode. */ + if (dev->regs[0] & 0x08) + length |= 0x80; /* ECP mode. */ + } + + return length; +} +#endif + + +static void +w83787f_serial_handler(w83787f_t *dev, int uart) +{ + int urs0 = !!(dev->regs[1] & (1 << uart)); + int urs1 = !!(dev->regs[1] & (4 << uart)); + int urs2 = !!(dev->regs[3] & (8 >> uart)); + int urs, irq = 4; + uint16_t addr = 0x3f8, enable = 1; + + urs = (urs1 << 1) | urs0; + + if (urs2) { + addr = uart ? 0x3f8 : 0x2f8; + irq = uart ? 4 : 3; + } else { + switch (urs) { + case 0: + addr = uart ? 0x3e8 : 0x2e8; + irq = uart ? 4 : 3; + break; + case 1: + addr = uart ? 0x2e8 : 0x3e8; + irq = uart ? 3 : 4; + break; + case 2: + addr = uart ? 0x2f8 : 0x3f8; + irq = uart ? 3 : 4; + break; + case 3: + default: + enable = 0; + break; + } + } + + if (dev->regs[4] & (0x20 >> uart)) + enable = 0; + + serial_remove(dev->uart[uart]); + if (enable) + serial_setup(dev->uart[uart], addr, irq); +} + + +static void +w83787f_lpt_handler(w83787f_t *dev) +{ + int ptrs0 = !!(dev->regs[1] & 4); + int ptrs1 = !!(dev->regs[1] & 5); + int ptrs, irq = 7; + uint16_t addr = 0x378, enable = 1; + + ptrs = (ptrs1 << 1) | ptrs0; + + switch (ptrs) { + case 0: + addr = 0x3bc; + irq = 7; + break; + case 1: + addr = 0x278; + irq = 5; + break; + case 2: + addr = 0x378; + irq = 7; + break; + case 3: + default: + enable = 0; + break; + } + + if (dev->regs[4] & 0x80) + enable = 0; + + lpt1_remove(); + if (enable) { + lpt1_init(addr); + lpt1_irq(irq); + } +} + + +static void +w83787f_fdc_handler(w83787f_t *dev) +{ + fdc_remove(dev->fdc); + if (!(dev->regs[0] & 0x20)) + fdc_set_base(dev->fdc, (dev->regs[0] & 0x10) ? 0x03f0 : 0x0370); +} + + +static void +w83787f_write(uint16_t port, uint8_t val, void *priv) +{ + w83787f_t *dev = (w83787f_t *) priv; + uint8_t valxor = 0; + uint8_t max = 0x15; + pclog("W83787F: Write %02X to %04X\n", val, port); + + if (port == 0x250) { + if (val == dev->key) + dev->locked = 1; + else + dev->locked = 0; + return; + } else if (port == 0x251) { + if (val <= max) + dev->cur_reg = val; + return; + } else { + if (dev->locked) { + if (dev->rw_locked) + return; + if (dev->cur_reg == 6) + val &= 0xF3; + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } else + return; + } + + switch (dev->cur_reg) { + case 0: + if (valxor & 0x30) + w83787f_fdc_handler(dev); + if (valxor & 0x0c) + w83787f_lpt_handler(dev); + break; + case 1: + if (valxor & 0x80) + fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); + if (valxor & 0x30) + w83787f_lpt_handler(dev); + if (valxor & 0x0a) + w83787f_serial_handler(dev, 1); + if (valxor & 0x05) + w83787f_serial_handler(dev, 0); + break; + case 3: + if (valxor & 0x80) + w83787f_lpt_handler(dev); + if (valxor & 0x08) + w83787f_serial_handler(dev, 0); + if (valxor & 0x04) + w83787f_serial_handler(dev, 1); + break; + case 4: + if (valxor & 0x10) + w83787f_serial_handler(dev, 1); + if (valxor & 0x20) + w83787f_serial_handler(dev, 0); + if (valxor & 0x80) + w83787f_lpt_handler(dev); + break; + case 6: + if (valxor & 0x08) { + fdc_remove(dev->fdc); + if (!(dev->regs[6] & 0x08)) + fdc_set_base(dev->fdc, 0x03f0); + } + break; + case 7: + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, FDDA_TYPE); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, FDDB_TYPE); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, FDDC_TYPE); + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, FDDD_TYPE); + break; + case 8: + if (valxor & 0x03) + fdc_update_boot_drive(dev->fdc, FD_BOOT); + if (valxor & 0x10) + fdc_set_swwp(dev->fdc, SWWP ? 1 : 0); + if (valxor & 0x20) + fdc_set_diswr(dev->fdc, DISFDDWR ? 1 : 0); + break; + case 9: + if (valxor & 0x20) + fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); + if (valxor & 0x40) + dev->rw_locked = (val & 0x40) ? 1 : 0; + if (valxor & 0x80) + w83787f_lpt_handler(dev); + break; + case 0xC: + if (valxor & 0x20) + w83787f_remap(dev); + break; + } +} + + +static uint8_t +w83787f_read(uint16_t port, void *priv) +{ + w83787f_t *dev = (w83787f_t *) priv; + uint8_t ret = 0xff; + + if (dev->locked) { + if (port == 0x251) + ret = dev->cur_reg; + else if (port == 0x252) { + if (dev->cur_reg == 7) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); + else if (!dev->rw_locked) + ret = dev->regs[dev->cur_reg]; + } + } + + pclog("W83787F: Read %02X from %04X\n", ret, port); + + return ret; +} + + +static void +w83787f_reset(w83787f_t *dev) +{ + lpt1_remove(); + lpt1_init(0x378); + lpt1_irq(7); + + fdc_reset(dev->fdc); + + memset(dev->regs, 0, 0x2A); + dev->regs[0x00] = 0x50; + dev->regs[0x01] = 0x2C; + dev->regs[0x03] = 0x30; + dev->regs[0x07] = 0xF5; + dev->regs[0x09] = dev->reg_init & 0xff; + dev->regs[0x0a] = 0x1F; + dev->regs[0x0c] = 0x2C; + dev->regs[0x0d] = 0xA3; + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + dev->key = 0x89; + + w83787f_remap(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + + +static void +w83787f_close(void *priv) +{ + w83787f_t *dev = (w83787f_t *) priv; + + free(dev); +} + + +static void * +w83787f_init(const device_t *info) +{ + w83787f_t *dev = (w83787f_t *) malloc(sizeof(w83787f_t)); + memset(dev, 0, sizeof(w83787f_t)); + + dev->fdc = device_add(&fdc_at_winbond_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->reg_init = info->local; + + w83787f_reset(dev); + + return dev; +} + + +const device_t w83787f_device = { + "Winbond W83787F/IF Super I/O", + 0, + 0x09, + w83787f_init, w83787f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_w83787f.d b/src/sio_w83787f.d new file mode 100644 index 000000000..d23ce26f9 --- /dev/null +++ b/src/sio_w83787f.d @@ -0,0 +1,3 @@ +sio_w83787f.o: sio_w83787f.c 86box.h device.h 86box_io.h timer.h \ + cpu_common/cpu.h pci.h mem.h rom.h lpt.h serial.h floppy/fdd.h \ + floppy/fdc.h sio.h diff --git a/src/sio_w83877f.c b/src/sio_w83877f.c index 69ad67286..dadce5a6c 100644 --- a/src/sio_w83877f.c +++ b/src/sio_w83877f.c @@ -11,7 +11,7 @@ * Winbond W83877F Super I/O Chip * Used by the Award 430HX * - * Version: @(#)sio_w83877f.c 1.0.16 2020/01/11 + * Version: @(#)sio_w83877f.c 1.0.17 2020/01/25 * * Author: Miran Grca, * Copyright 2016-2020 Miran Grca. @@ -23,15 +23,15 @@ #include #include "86box.h" #include "device.h" -#include "io.h" +#include "86box_io.h" #include "timer.h" #include "pci.h" #include "mem.h" #include "rom.h" #include "lpt.h" #include "serial.h" -#include "floppy/fdd.h" -#include "floppy/fdc.h" +#include "fdd.h" +#include "fdc.h" #include "sio.h" @@ -148,18 +148,65 @@ make_port(w83877f_t *dev, uint8_t reg) } +static void +w83877f_fdc_handler(w83877f_t *dev) +{ + fdc_remove(dev->fdc); + if (!(dev->regs[6] & 0x08) && (dev->regs[0x20] & 0xc0)) + fdc_set_base(dev->fdc, 0x03f0); +} + + +static void +w83877f_lpt_handler(w83877f_t *dev) +{ + uint8_t lpt_irq; + uint8_t lpt_irqs[8] = { 0, 7, 9, 10, 11, 14, 15, 5 }; + + lpt1_remove(); + if (!(dev->regs[4] & 0x80) && (dev->regs[0x23] & 0xc0)) + lpt1_init(make_port(dev, 0x23)); + + lpt_irq = 0xff; + + lpt_irq = lpt_irqs[ECPIRQ]; + if (lpt_irq == 0) + lpt_irq = PRTIQS; + + lpt1_irq(lpt_irq); +} + + static void w83877f_serial_handler(w83877f_t *dev, int uart) { int reg_mask = uart ? 0x10 : 0x20; - int reg_id = uart ? 0x24 : 0x25; + int reg_id = uart ? 0x25 : 0x24; int irq_mask = uart ? 0x0f : 0xf0; - int irq_shift = uart ? 4 : 0; + int irq_shift = uart ? 0 : 4; + double clock_src = 24000000.0 / 13.0; - if ((dev->regs[4] & reg_mask) || !(dev->regs[reg_id] & 0xc0)) - serial_remove(dev->uart[uart]); - else + serial_remove(dev->uart[uart]); + if (!(dev->regs[4] & reg_mask) && (dev->regs[reg_id] & 0xc0)) serial_setup(dev->uart[uart], make_port(dev, reg_id), (dev->regs[0x28] & irq_mask) >> irq_shift); + + switch (!!(dev->regs[0x19] & (0x02 >> uart))) { + case 0: + switch (!!(dev->regs[0x03] & (0x02 >> uart))) { + case 0: + clock_src = 24000000.0 / 13.0; + break; + case 1: + clock_src = 24000000.0 / 12.0; + break; + } + break; + case 1: + clock_src = 14769000.0; + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); } @@ -169,7 +216,6 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) w83877f_t *dev = (w83877f_t *) priv; uint8_t valxor = 0; uint8_t max = 0x2A; - uint8_t lpt_irq; if (port == 0x250) { if (val == dev->key) @@ -207,6 +253,7 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) return; } else if ((port == 0x252) || (port == 0x3f1)) { if (dev->locked) { + pclog("dev->locked\n"); if (dev->rw_locked) return; if ((dev->cur_reg >= 0x26) && (dev->cur_reg <= 0x27)) @@ -223,33 +270,30 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0: - if (valxor & 0x0c) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor & 0x0c) + w83877f_lpt_handler(dev); break; case 1: if (valxor & 0x80) fdc_set_swap(dev->fdc, (dev->regs[1] & 0x80) ? 1 : 0); break; + case 3: + if (valxor & 0x02) + w83877f_serial_handler(dev, 0); + if (valxor & 0x01) + w83877f_serial_handler(dev, 1); + break; case 4: if (valxor & 0x10) w83877f_serial_handler(dev, 1); if (valxor & 0x20) w83877f_serial_handler(dev, 0); - if (valxor & 0x80) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor & 0x80) + w83877f_lpt_handler(dev); break; case 6: - if (valxor & 0x08) { - fdc_remove(dev->fdc); - if (!(dev->regs[6] & 0x08)) - fdc_set_base(dev->fdc, 0x03f0); - } + if (valxor & 0x08) + w83877f_fdc_handler(dev); break; case 7: if (valxor & 0x03) @@ -274,11 +318,8 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) fdc_update_enh_mode(dev->fdc, EN3MODE ? 1 : 0); if (valxor & 0x40) dev->rw_locked = (val & 0x40) ? 1 : 0; - if (valxor & 0x80) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor & 0x80) + w83877f_lpt_handler(dev); break; case 0xB: if (valxor & 1) @@ -294,19 +335,19 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) if (valxor & 1) w83877f_remap(dev); break; + case 0x19: + if (valxor & 0x02) + w83877f_serial_handler(dev, 0); + if (valxor & 0x01) + w83877f_serial_handler(dev, 1); + break; case 0x20: - if (valxor) { - fdc_remove(dev->fdc); - if (!(dev->regs[4] & 0x80)) - fdc_set_base(dev->fdc, make_port(dev, 0x20)); - } + if (valxor) + w83877f_fdc_handler(dev); break; case 0x23: - if (valxor) { - lpt1_remove(); - if (!(dev->regs[4] & 0x80)) - lpt1_init(make_port(dev, 0x23)); - } + if (valxor) + w83877f_lpt_handler(dev); break; case 0x24: if (valxor & 0xfe) @@ -317,27 +358,19 @@ w83877f_write(uint16_t port, uint8_t val, void *priv) w83877f_serial_handler(dev, 1); break; case 0x27: - if (valxor & 0xef) { - lpt_irq = 0xff; - - if (PRTIQS != 0x00) - lpt_irq = ECPIRQ; - - lpt1_irq(lpt_irq); - } + if (valxor & 0xef) + w83877f_lpt_handler(dev); break; case 0x28: if (valxor & 0xf) { if ((dev->regs[0x28] & 0x0f) == 0) dev->regs[0x28] |= 0x03; - if (!(dev->regs[2] & 0x10)) - serial_setup(dev->uart[1], make_port(dev, 0x25), dev->regs[0x28] & 0x0f); + w83877f_serial_handler(dev, 1); } if (valxor & 0xf0) { if ((dev->regs[0x28] & 0xf0) == 0) dev->regs[0x28] |= 0x40; - if (!(dev->regs[4] & 0x20)) - serial_setup(dev->uart[0], make_port(dev, 0x24), (dev->regs[0x28] & 0xf0) >> 4); + w83877f_serial_handler(dev, 0); } break; } @@ -355,7 +388,7 @@ w83877f_read(uint16_t port, void *priv) ret = dev->cur_reg; else if ((port == 0x3f1) || (port == 0x252)) { if (dev->cur_reg == 7) - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2)); + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); else if ((dev->cur_reg >= 0x18) || !dev->rw_locked) ret = dev->regs[dev->cur_reg]; } @@ -368,9 +401,6 @@ w83877f_read(uint16_t port, void *priv) static void w83877f_reset(w83877f_t *dev) { - lpt1_remove(); - lpt1_init(0x378); - fdc_reset(dev->fdc); memset(dev->regs, 0, 0x2A); @@ -389,12 +419,16 @@ w83877f_reset(w83877f_t *dev) dev->regs[0x24] = (0x3f8 >> 2) & 0xfe; dev->regs[0x25] = (0x2f8 >> 2) & 0xfe; dev->regs[0x26] = (2 << 4) | 4; - dev->regs[0x27] = (6 << 4) | 7; + dev->regs[0x27] = (2 << 4) | 5; dev->regs[0x28] = (4 << 4) | 3; dev->regs[0x29] = 0x62; - serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); - serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + w83877f_fdc_handler(dev); + + w83877f_lpt_handler(dev); + + w83877f_serial_handler(dev, 0); + w83877f_serial_handler(dev, 1); dev->base_address = 0x3f0; dev->key = 0x89; @@ -463,3 +497,13 @@ const device_t w83877tf_device = { NULL, NULL, NULL, NULL }; + + +const device_t w83877tf_acorp_device = { + "Winbond W83877TF Super I/O", + 0, + 0x0c05, + w83877f_init, w83877f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_w83877f.d b/src/sio_w83877f.d new file mode 100644 index 000000000..9b8edfbaf --- /dev/null +++ b/src/sio_w83877f.d @@ -0,0 +1,3 @@ +sio_w83877f.o: sio_w83877f.c 86box.h device.h 86box_io.h timer.h \ + cpu_common/cpu.h pci.h mem.h rom.h lpt.h serial.h floppy/fdd.h \ + floppy/fdc.h sio.h diff --git a/src/sio_w83977f.c b/src/sio_w83977f.c new file mode 100644 index 000000000..286aa074a --- /dev/null +++ b/src/sio_w83977f.c @@ -0,0 +1,519 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83977F Super I/O Chip. + * + * Winbond W83977F Super I/O Chip + * Used by the Award 430TX + * + * Version: @(#)sio_w83977f.c 1.0.0 2020/01/24 + * + * Author: Miran Grca, + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "pci.h" +#include "mem.h" +#include "rom.h" +#include "lpt.h" +#include "serial.h" +#include "fdd.h" +#include "fdc.h" +#include "sio.h" + + +#define HEFRAS (dev->regs[0x26] & 0x40) + + +typedef struct { + uint8_t tries, regs[48], + dev_regs[256][208]; + int locked, rw_locked, + cur_reg, base_address, + type; + fdc_t *fdc; + serial_t *uart[2]; +} w83977f_t; + + +static void w83977f_write(uint16_t port, uint8_t val, void *priv); +static uint8_t w83977f_read(uint16_t port, void *priv); + + +static void +w83977f_remap(w83977f_t *dev) +{ + io_removehandler(0x3f0, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + io_removehandler(0x370, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); + + dev->base_address = (HEFRAS ? 0x370 : 0x3f0); + + io_sethandler(dev->base_address, 0x0002, + w83977f_read, NULL, NULL, w83977f_write, NULL, NULL, dev); +} + + +static uint8_t +get_lpt_length(w83977f_t *dev) +{ + uint8_t length = 4; + + if (((dev->dev_regs[1][0xc0] & 0x07) != 0x00) && ((dev->dev_regs[1][0xc0] & 0x07) != 0x02) && + ((dev->dev_regs[1][0xc0] & 0x07) != 0x04)) + length = 8; + + return length; +} + + +static void +w83977f_fdc_handler(w83977f_t *dev) +{ + uint16_t io_base = (dev->dev_regs[0][0x30] << 8) | dev->dev_regs[0][0x31]; + + fdc_remove(dev->fdc); + + pclog("fdc: %02X %02X %04X\n", dev->dev_regs[0][0x00], dev->regs[0x22], io_base); + if ((dev->dev_regs[0][0x00] & 0x01) && (dev->regs[0x22] & 0x01) && (io_base >= 0x100) && (io_base <= 0xff8)) + fdc_set_base(dev->fdc, io_base); + + fdc_set_irq(dev->fdc, dev->dev_regs[0][0x40] & 0x0f); +} + + +static void +w83977f_lpt_handler(w83977f_t *dev) +{ + uint16_t io_mask, io_base = (dev->dev_regs[1][0x30] << 8) | dev->dev_regs[1][0x31]; + int io_len = get_lpt_length(dev); + io_base &= (0xfff & ~io_len); + io_mask = 0xffc; + if (io_len == 8) + io_mask = 0xff8; + + lpt1_remove(); + + if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) + lpt1_init(io_base); + + lpt1_irq(dev->dev_regs[1][0x40] & 0x0f); +} + + +static void +w83977f_serial_handler(w83977f_t *dev, int uart) +{ + uint16_t io_base = (dev->dev_regs[2 + uart][0x30] << 8) | dev->dev_regs[2 + uart][0x31]; + double clock_src = 24000000.0 / 13.0; + + serial_remove(dev->uart[uart]); + + if ((dev->dev_regs[2 + uart][0x00] & 0x01) && (dev->regs[0x22] & (0x10 << uart)) && (io_base >= 0x100) && (io_base <= 0xff8)) + serial_setup(dev->uart[uart], io_base, dev->dev_regs[2 + uart][0x40] & 0x0f); + + switch (dev->dev_regs[2 + uart][0xc0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); +} + + +static void +w83977f_write(uint16_t port, uint8_t val, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0; + uint8_t ld = dev->regs[7]; + + pclog("W83977F Write: %04X %02X\n", port, val); + + if (index) { + if ((val == 0x87) && !dev->locked) { + if (dev->tries) { + dev->locked = 1; + dev->tries = 0; + } else + dev->tries++; + } else { + if (dev->locked) { + if (val == 0xaa) + dev->locked = 0; + else + dev->cur_reg = val; + } else { + if (dev->tries) + dev->tries = 0; + } + } + return; + } else { + if (dev->locked) { + if (dev->rw_locked) + return; + if (dev->cur_reg >= 0x30) { + valxor = val ^ dev->dev_regs[ld][dev->cur_reg - 0x30]; + dev->dev_regs[ld][dev->cur_reg - 0x30] = val; + } else { + valxor = val ^ dev->regs[dev->cur_reg]; + dev->regs[dev->cur_reg] = val; + } + } else + return; + } + + switch (dev->cur_reg) { + case 0x02: + if (valxor & 0x02) + softresetx86(); + break; + case 0x22: + if (valxor & 0x20) + w83977f_serial_handler(dev, 1); + if (valxor & 0x10) + w83977f_serial_handler(dev, 0); + if (valxor & 0x08) + w83977f_lpt_handler(dev); + if (valxor & 0x01) + w83977f_fdc_handler(dev); + break; + case 0x26: + if (valxor & 0x20) + dev->rw_locked = (val & 0x20) ? 1 : 0; + case 0x30: + if (valxor & 0x01) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x60: case 0x61: + if (valxor & 0xff) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0x70: + if (valxor & 0x0f) switch (ld) { + case 0x00: + w83977f_fdc_handler(dev); + break; + case 0x01: + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf0: + switch (ld) { + case 0x00: + if (valxor & 0x20) + fdc_update_drv2en(dev->fdc, (val & 0x20) ? 0 : 1); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) ? 1 : 0); + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, (val & 0x01) ? 1 : 0); + break; + case 0x01: + if (valxor & 0x07) + w83977f_lpt_handler(dev); + break; + case 0x02: case 0x03: + if (valxor & 0x03) + w83977f_serial_handler(dev, ld - 2); + break; + } + break; + case 0xf1: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_boot_drive(dev->fdc, (val & 0xc0) >> 6); + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0x0c) >> 2); + if (valxor & 0x02) + fdc_set_diswr(dev->fdc, (val & 0x02) ? 1 : 0); + if (valxor & 0x01) + fdc_set_swwp(dev->fdc, (val & 0x01) ? 1 : 0); + break; + } + break; + case 0xf2: + switch (ld) { + case 0x00: + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, val & 0x03); + break; + } + break; + case 0xf4: case 0xf5: case 0xf6: case 0xf7: + switch (ld) { + case 0x00: + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg & 0x03, (val & 0x18) >> 3); + break; + } + break; + } +} + + +static uint8_t +w83977f_read(uint16_t port, void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + uint8_t ret = 0xff; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ld = dev->regs[7]; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (!dev->rw_locked) { + if ((dev->cur_reg == 0xf2) && (ld == 0x00)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if (dev->cur_reg >= 0x30) + ret = dev->dev_regs[ld][dev->cur_reg - 0x30]; + else + ret = dev->regs[dev->cur_reg]; + } + } + } + + pclog("W83977F Read: %04X %02X\n", port, ret); + + return ret; +} + + +static void +w83977f_reset(w83977f_t *dev) +{ + int i; + + memset(dev->regs, 0, 48); + for (i = 0; i < 256; i++) + memset(dev->dev_regs[i], 0, 208); + + dev->regs[0x20] = 0x97; + dev->regs[0x21] = dev->type ? 0x73 : 0x71; + dev->regs[0x22] = 0xff; + dev->regs[0x24] = dev->type ? 0x84 : 0xa4; + + /* WARNING: Array elements are register - 0x30. */ + /* Logical Device 0 (FDC) */ + dev->dev_regs[0][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[0][0x01] = 0x02; + dev->dev_regs[0][0x30] = 0x03; dev->dev_regs[0][0x31] = 0xf0; + dev->dev_regs[0][0x40] = 0x06; + if (!dev->type) + dev->dev_regs[0][0x41] = 0x02; /* Read-only */ + dev->dev_regs[0][0x44] = 0x02; + dev->dev_regs[0][0xc0] = 0x0e; + + /* Logical Device 1 (Parallel Port) */ + dev->dev_regs[1][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[1][0x01] = 0x02; + dev->dev_regs[1][0x30] = 0x03; dev->dev_regs[1][0x31] = 0x78; + dev->dev_regs[1][0x40] = 0x07; + if (!dev->type) + dev->dev_regs[1][0x41] = 0x02; /* Read-only */ + dev->dev_regs[1][0x44] = 0x04; + dev->dev_regs[1][0xc0] = 0x3c; /* The datasheet says default is 3f, but also default is priner mode. */ + + /* Logical Device 2 (UART A) */ + dev->dev_regs[2][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[2][0x01] = 0x02; + dev->dev_regs[2][0x30] = 0x03; dev->dev_regs[2][0x31] = 0xf8; + dev->dev_regs[2][0x40] = 0x04; + if (!dev->type) + dev->dev_regs[2][0x41] = 0x02; /* Read-only */ + + /* Logical Device 3 (UART B) */ + dev->dev_regs[3][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[3][0x01] = 0x02; + dev->dev_regs[3][0x30] = 0x02; dev->dev_regs[3][0x31] = 0xf8; + dev->dev_regs[3][0x40] = 0x03; + if (!dev->type) + dev->dev_regs[3][0x41] = 0x02; /* Read-only */ + + /* Logical Device 4 (RTC) */ + if (!dev->type) { + dev->dev_regs[4][0x00] = 0x01; + dev->dev_regs[4][0x01] = 0x02; + dev->dev_regs[4][0x30] = 0x00; dev->dev_regs[4][0x31] = 0x70; + dev->dev_regs[4][0x40] = 0x08; + dev->dev_regs[4][0x41] = 0x02; /* Read-only */ + } + + /* Logical Device 5 (KBC) */ + dev->dev_regs[5][0x00] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x01] = 0x02; + dev->dev_regs[5][0x30] = 0x00; dev->dev_regs[5][0x31] = 0x60; + dev->dev_regs[5][0x40] = 0x01; + if (!dev->type) + dev->dev_regs[5][0x41] = 0x02; /* Read-only */ + dev->dev_regs[5][0x42] = 0x0c; + if (!dev->type) + dev->dev_regs[5][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[5][0xc0] = dev->type ? 0x83 : 0x40; + + /* Logical Device 6 (IR) = UART C */ + if (!dev->type) { + dev->dev_regs[6][0x01] = 0x02; + dev->dev_regs[6][0x41] = 0x02; /* Read-only */ + dev->dev_regs[6][0x44] = 0x04; + dev->dev_regs[6][0x45] = 0x04; + } + + /* Logical Device 7 (Auxiliary I/O Part I) */ + if (!dev->type) + dev->dev_regs[7][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[7][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[7][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; + if (dev->type) + dev->dev_regs[7][0xb7] = 0x01; + + /* Logical Device 8 (Auxiliary I/O Part II) */ + if (!dev->type) + dev->dev_regs[8][0x01] = 0x02; + if (!dev->type) + dev->dev_regs[8][0x41] = 0x02; /* Read-only */ + if (!dev->type) + dev->dev_regs[8][0x43] = 0x02; /* Read-only? */ + dev->dev_regs[8][0xb8] = 0x01; dev->dev_regs[8][0xb9] = 0x01; + dev->dev_regs[8][0xba] = 0x01; dev->dev_regs[8][0xbb] = 0x01; + dev->dev_regs[8][0xbc] = 0x01; dev->dev_regs[8][0xbd] = 0x01; + dev->dev_regs[8][0xbe] = 0x01; dev->dev_regs[8][0xbf] = 0x01; + + /* Logical Device 9 (Auxiliary I/O Part III) */ + if (dev->type) { + dev->dev_regs[7][0xb0] = 0x01; dev->dev_regs[7][0xb1] = 0x01; + dev->dev_regs[7][0xb2] = 0x01; dev->dev_regs[7][0xb3] = 0x01; + dev->dev_regs[7][0xb4] = 0x01; dev->dev_regs[7][0xb5] = 0x01; + dev->dev_regs[7][0xb6] = 0x01; dev->dev_regs[7][0xb7] = 0x01; + } + + fdc_reset(dev->fdc); + + serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(dev->uart[1], SERIAL2_ADDR, SERIAL2_IRQ); + + w83977f_fdc_handler(dev); + w83977f_lpt_handler(dev); + w83977f_serial_handler(dev, 0); + w83977f_serial_handler(dev, 1); + + w83977f_remap(dev); + + dev->locked = 0; + dev->rw_locked = 0; +} + + +static void +w83977f_close(void *priv) +{ + w83977f_t *dev = (w83977f_t *) priv; + + free(dev); +} + + +static void * +w83977f_init(const device_t *info) +{ + w83977f_t *dev = (w83977f_t *) malloc(sizeof(w83977f_t)); + memset(dev, 0, sizeof(w83977f_t)); + + dev->type = info->local; + + dev->fdc = device_add(&fdc_at_smc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + w83977f_reset(dev); + + return dev; +} + + +const device_t w83977f_device = { + "Winbond W83977F Super I/O", + 0, + 0, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; + + +const device_t w83977tf_device = { + "Winbond W83977TF Super I/O", + 0, + 1, + w83977f_init, w83977f_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/sio_w83977f.d b/src/sio_w83977f.d new file mode 100644 index 000000000..0c2415187 --- /dev/null +++ b/src/sio_w83977f.d @@ -0,0 +1,3 @@ +sio_w83977f.o: sio_w83977f.c 86box.h device.h 86box_io.h timer.h \ + cpu_common/cpu.h pci.h mem.h rom.h lpt.h serial.h floppy/fdd.h \ + floppy/fdc.h sio.h diff --git a/src/sis_85c471.d b/src/sis_85c471.d new file mode 100644 index 000000000..0e7c4e80f --- /dev/null +++ b/src/sis_85c471.d @@ -0,0 +1,3 @@ +sis_85c471.o: chipset/sis_85c471.c 86box.h cpu_common/cpu.h mem.h \ + 86box_io.h lpt.h rom.h pci.h device.h disk/hdc_ide.h keyboard.h timer.h \ + port_92.h serial.h machine/machine.h chipset/chipset.h diff --git a/src/sis_85c496.d b/src/sis_85c496.d new file mode 100644 index 000000000..8e19afc11 --- /dev/null +++ b/src/sis_85c496.d @@ -0,0 +1,3 @@ +sis_85c496.o: chipset/sis_85c496.c 86box.h cpu_common/cpu.h mem.h \ + 86box_io.h rom.h pci.h device.h keyboard.h timer.h port_92.h \ + disk/hdc_ide.h machine/machine.h chipset/chipset.h diff --git a/src/slirp.d b/src/slirp.d new file mode 100644 index 000000000..6152e3669 --- /dev/null +++ b/src/slirp.d @@ -0,0 +1,9 @@ +slirp.o: network/slirp/slirp.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/snd_ad1848.d b/src/snd_ad1848.d new file mode 100644 index 000000000..e298d3867 --- /dev/null +++ b/src/snd_ad1848.d @@ -0,0 +1,2 @@ +snd_ad1848.o: sound/snd_ad1848.c 86box.h dma.h pic.h timer.h \ + cpu_common/cpu.h sound/sound.h sound/snd_ad1848.h diff --git a/src/snd_adlib.d b/src/snd_adlib.d new file mode 100644 index 000000000..40d1f7b7f --- /dev/null +++ b/src/snd_adlib.d @@ -0,0 +1,2 @@ +snd_adlib.o: sound/snd_adlib.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mca.h device.h sound/sound.h sound/snd_opl.h diff --git a/src/snd_adlibgold.d b/src/snd_adlibgold.d new file mode 100644 index 000000000..cfb32bb50 --- /dev/null +++ b/src/snd_adlibgold.d @@ -0,0 +1,3 @@ +snd_adlibgold.o: sound/snd_adlibgold.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h dma.h pic.h device.h nvr.h sound/sound.h \ + sound/filters.h sound/snd_opl.h sound/snd_ym7128.h diff --git a/src/snd_audiopci.d b/src/snd_audiopci.d new file mode 100644 index 000000000..a9260d666 --- /dev/null +++ b/src/snd_audiopci.d @@ -0,0 +1,3 @@ +snd_audiopci.o: sound/snd_audiopci.c 86box.h device.h 86box_io.h nmi.h \ + mem.h pci.h timer.h cpu_common/cpu.h sound/sound.h sound/midi.h \ + sound/snd_mpu401.h diff --git a/src/snd_cms.d b/src/snd_cms.d new file mode 100644 index 000000000..dc1aecdfe --- /dev/null +++ b/src/snd_cms.d @@ -0,0 +1 @@ +snd_cms.o: sound/snd_cms.c 86box.h 86box_io.h device.h sound/sound.h diff --git a/src/snd_emu8k.d b/src/snd_emu8k.d new file mode 100644 index 000000000..792c6d340 --- /dev/null +++ b/src/snd_emu8k.d @@ -0,0 +1,2 @@ +snd_emu8k.o: sound/snd_emu8k.c 86box.h device.h 86box_io.h mem.h rom.h \ + timer.h cpu_common/cpu.h sound/sound.h sound/snd_emu8k.h diff --git a/src/snd_gus.d b/src/snd_gus.d new file mode 100644 index 000000000..cf6ca53d5 --- /dev/null +++ b/src/snd_gus.d @@ -0,0 +1,2 @@ +snd_gus.o: sound/snd_gus.c 86box.h 86box_io.h nmi.h pic.h dma.h timer.h \ + cpu_common/cpu.h device.h sound/sound.h sound/midi.h diff --git a/src/snd_lpt_dac.d b/src/snd_lpt_dac.d new file mode 100644 index 000000000..e1b103898 --- /dev/null +++ b/src/snd_lpt_dac.d @@ -0,0 +1,2 @@ +snd_lpt_dac.o: sound/snd_lpt_dac.c 86box.h cpu_common/cpu.h \ + machine/machine.h lpt.h timer.h sound/sound.h sound/filters.h diff --git a/src/snd_lpt_dss.d b/src/snd_lpt_dss.d new file mode 100644 index 000000000..12f36e6d9 --- /dev/null +++ b/src/snd_lpt_dss.d @@ -0,0 +1,2 @@ +snd_lpt_dss.o: sound/snd_lpt_dss.c 86box.h cpu_common/cpu.h \ + machine/machine.h timer.h lpt.h sound/sound.h sound/filters.h diff --git a/src/snd_mpu401.d b/src/snd_mpu401.d new file mode 100644 index 000000000..34133a7a2 --- /dev/null +++ b/src/snd_mpu401.d @@ -0,0 +1,3 @@ +snd_mpu401.o: sound/snd_mpu401.c 86box.h device.h plat.h lang/language.h \ + 86box_io.h machine/machine.h mca.h pic.h timer.h cpu_common/cpu.h \ + sound/sound.h sound/snd_mpu401.h sound/midi.h diff --git a/src/snd_opl.d b/src/snd_opl.d new file mode 100644 index 000000000..deae64151 --- /dev/null +++ b/src/snd_opl.d @@ -0,0 +1,2 @@ +snd_opl.o: sound/snd_opl.c 86box.h cpu_common/cpu.h 86box_io.h timer.h \ + sound/sound.h sound/snd_opl.h sound/snd_opl_backend.h diff --git a/src/snd_opl_backend.d b/src/snd_opl_backend.d new file mode 100644 index 000000000..715df9644 --- /dev/null +++ b/src/snd_opl_backend.d @@ -0,0 +1,2 @@ +snd_opl_backend.o: sound/snd_opl_backend.c 86box.h sound/nukedopl.h \ + sound/sound.h sound/snd_opl_backend.h cpu_common/cpu.h mem.h diff --git a/src/snd_pssj.d b/src/snd_pssj.d new file mode 100644 index 000000000..90007782c --- /dev/null +++ b/src/snd_pssj.d @@ -0,0 +1,2 @@ +snd_pssj.o: sound/snd_pssj.c 86box.h 86box_io.h dma.h pic.h timer.h \ + cpu_common/cpu.h device.h sound/sound.h sound/snd_sn76489.h diff --git a/src/snd_resid.d b/src/snd_resid.d new file mode 100644 index 000000000..1f5f210fb --- /dev/null +++ b/src/snd_resid.d @@ -0,0 +1,5 @@ +snd_resid.o: sound/snd_resid.cc sound/resid-fp/sid.h \ + sound/resid-fp/siddefs-fp.h sound/resid-fp/voice.h sound/resid-fp/wave.h \ + sound/resid-fp/envelope.h sound/resid-fp/filter.h \ + sound/resid-fp/extfilt.h sound/resid-fp/pot.h plat.h lang/language.h \ + sound/snd_resid.h diff --git a/src/snd_sb.d b/src/snd_sb.d new file mode 100644 index 000000000..be1b51fb8 --- /dev/null +++ b/src/snd_sb.d @@ -0,0 +1,4 @@ +snd_sb.o: sound/snd_sb.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + mca.h mem.h rom.h device.h pic.h sound/sound.h sound/midi.h \ + sound/filters.h sound/snd_emu8k.h sound/snd_mpu401.h sound/snd_opl.h \ + sound/snd_sb_dsp.h diff --git a/src/snd_sb_dsp.d b/src/snd_sb_dsp.d new file mode 100644 index 000000000..bf4f2bb75 --- /dev/null +++ b/src/snd_sb_dsp.d @@ -0,0 +1,3 @@ +snd_sb_dsp.o: sound/snd_sb_dsp.c 86box.h 86box_io.h pic.h dma.h timer.h \ + cpu_common/cpu.h device.h sound/filters.h sound/sound.h sound/midi.h \ + sound/snd_mpu401.h sound/snd_sb_dsp.h diff --git a/src/snd_sn76489.d b/src/snd_sn76489.d new file mode 100644 index 000000000..506fbf796 --- /dev/null +++ b/src/snd_sn76489.d @@ -0,0 +1,2 @@ +snd_sn76489.o: sound/snd_sn76489.c 86box.h 86box_io.h device.h \ + sound/sound.h sound/snd_sn76489.h diff --git a/src/snd_speaker.d b/src/snd_speaker.d new file mode 100644 index 000000000..923b5cf08 --- /dev/null +++ b/src/snd_speaker.d @@ -0,0 +1,2 @@ +snd_speaker.o: sound/snd_speaker.c 86box.h timer.h cpu_common/cpu.h pit.h \ + sound/sound.h sound/snd_speaker.h diff --git a/src/snd_ssi2001.d b/src/snd_ssi2001.d new file mode 100644 index 000000000..773b4195b --- /dev/null +++ b/src/snd_ssi2001.d @@ -0,0 +1,2 @@ +snd_ssi2001.o: sound/snd_ssi2001.c 86box.h 86box_io.h device.h \ + sound/sound.h sound/snd_resid.h diff --git a/src/snd_wss.d b/src/snd_wss.d new file mode 100644 index 000000000..0db5e2916 --- /dev/null +++ b/src/snd_wss.d @@ -0,0 +1,3 @@ +snd_wss.o: sound/snd_wss.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + mca.h pic.h dma.h device.h sound/sound.h sound/snd_ad1848.h \ + sound/snd_opl.h diff --git a/src/snd_ym7128.d b/src/snd_ym7128.d new file mode 100644 index 000000000..124455567 --- /dev/null +++ b/src/snd_ym7128.d @@ -0,0 +1 @@ +snd_ym7128.o: sound/snd_ym7128.c 86box.h sound/snd_ym7128.h diff --git a/src/socket.d b/src/socket.d new file mode 100644 index 000000000..d6ed34c6a --- /dev/null +++ b/src/socket.d @@ -0,0 +1,9 @@ +socket.o: network/slirp/socket.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h network/slirp/ip_icmp.h diff --git a/src/sound.d b/src/sound.d new file mode 100644 index 000000000..4ef78a1d5 --- /dev/null +++ b/src/sound.d @@ -0,0 +1,4 @@ +sound.o: sound/sound.c 86box.h device.h timer.h cpu_common/cpu.h \ + cdrom/cdrom.h disk/hdc_ide.h plat.h lang/language.h sound/sound.h \ + sound/midi.h sound/snd_opl.h sound/snd_mpu401.h sound/snd_sb_dsp.h \ + sound/filters.h diff --git a/src/sound/midi.c b/src/sound/midi.c index 709b83faa..3c7da9966 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -25,18 +25,11 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_midi.h" #include "midi.h" -#include "midi_system.h" -#ifdef USE_FLUIDSYNTH -# include "midi_fluidsynth.h" -#endif -#ifdef USE_MUNT -# include "midi_mt32.h" -#endif #include "midi_input.h" diff --git a/src/sound/midi.h b/src/sound/midi.h index a0e89a50d..a41f369da 100644 --- a/src/sound/midi.h +++ b/src/sound/midi.h @@ -11,7 +11,7 @@ extern int midi_device_current; extern int midi_input_device_current; extern void (*input_msg)(void *p, uint8_t *msg); -extern int (*input_sysex)(void *p, uint8_t *buffer, uint32_t len, int abort); +extern int (*input_sysex)(void *p, uint8_t *buf, uint32_t len, int abort); extern void *midi_in_p; int midi_device_available(int card); @@ -96,4 +96,15 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #define MIDI_INPUT_NAME "MIDI Input Device" #define MIDI_INPUT_INTERNAL_NAME "midi_in" +#ifdef EMU_DEVICE_H +extern const device_t system_midi_device; +#ifdef USE_FLUIDSYNTH +extern const device_t fluidsynth_device; +#endif +#ifdef USE_MUNT +extern const device_t mt32_device; +extern const device_t cm32l_device; +#endif +#endif + #endif /*EMU_SOUND_MIDI_H*/ diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 822213d11..6a3f42c08 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -5,14 +5,13 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" #include "midi.h" -#include "midi_fluidsynth.h" #include "sound.h" diff --git a/src/sound/midi_fluidsynth.h b/src/sound/midi_fluidsynth.h deleted file mode 100644 index 518b1461d..000000000 --- a/src/sound/midi_fluidsynth.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t fluidsynth_device; diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index c62d98da2..1d6707d11 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -4,14 +4,13 @@ #include #include #include "munt/c_interface/c_interface.h" -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../rom.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "rom.h" +#include "plat.h" #include "sound.h" #include "midi.h" -#include "midi_mt32.h" extern void givealbuffer_midi(void *buf, uint32_t size); diff --git a/src/sound/midi_mt32.h b/src/sound/midi_mt32.h deleted file mode 100644 index 0aa012fa1..000000000 --- a/src/sound/midi_mt32.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const device_t mt32_device; -extern const device_t cm32l_device; diff --git a/src/sound/midi_system.c b/src/sound/midi_system.c index 6ee56b01a..90c9bc36e 100644 --- a/src/sound/midi_system.c +++ b/src/sound/midi_system.c @@ -3,12 +3,11 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_midi.h" #include "midi.h" -#include "midi_system.h" #include "midi_input.h" diff --git a/src/sound/openal.c b/src/sound/openal.c index 185730a57..ad0d5f957 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -29,7 +29,7 @@ # include # include # include -#include "../86box.h" +#include "86box.h" #include "sound.h" #include "midi.h" diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index fd5631b12..f8681ff86 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -7,10 +7,10 @@ #include #include #include -#include "../86box.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" +#include "86box.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" #include "sound.h" #include "snd_ad1848.h" diff --git a/src/sound/snd_ad1848.h b/src/sound/snd_ad1848.h index 6ec719475..0778cdfec 100644 --- a/src/sound/snd_ad1848.h +++ b/src/sound/snd_ad1848.h @@ -18,7 +18,7 @@ typedef struct ad1848_t int freq; pc_timer_t timer_count; - uint64_t timer_latch; + uint64_t timer_latch; int16_t buffer[SOUNDBUFLEN * 2]; int pos; diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index c0417f69d..29ace4e49 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -5,13 +5,12 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "device.h" #include "sound.h" -#include "snd_adlib.h" #include "snd_opl.h" diff --git a/src/sound/snd_adlib.h b/src/sound/snd_adlib.h deleted file mode 100644 index 4a6a161ca..000000000 --- a/src/sound/snd_adlib.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const device_t adlib_device; -extern const device_t adlib_mca_device; diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index d4a29412d..c45f85b41 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -3,13 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../dma.h" -#include "../pic.h" -#include "../device.h" -#include "../nvr.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "dma.h" +#include "pic.h" +#include "device.h" +#include "nvr.h" #include "sound.h" #include "filters.h" #include "snd_opl.h" diff --git a/src/sound/snd_adlibgold.h b/src/sound/snd_adlibgold.h deleted file mode 100644 index daea1b490..000000000 --- a/src/sound/snd_adlibgold.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t adgold_device; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 2068710a9..5e87c993d 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -5,17 +5,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../nmi.h" -#include "../mem.h" -#include "../pci.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "nmi.h" +#include "mem.h" +#include "pci.h" +#include "timer.h" #include "sound.h" #include "midi.h" #include "snd_mpu401.h" -#include "snd_audiopci.h" #define N 16 diff --git a/src/sound/snd_audiopci.h b/src/sound/snd_audiopci.h deleted file mode 100644 index 66600ed24..000000000 --- a/src/sound/snd_audiopci.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t es1371_device; diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 5d3e73c8d..829399932 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -5,11 +5,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "device.h" #include "sound.h" -#include "snd_cms.h" #define MASTER_CLOCK 7159090 diff --git a/src/sound/snd_cms.h b/src/sound/snd_cms.h deleted file mode 100644 index 41b6d6059..000000000 --- a/src/sound/snd_cms.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t cms_device; diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 9be46bb4c..946d8b7f6 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -7,12 +7,12 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" #include "sound.h" #include "snd_emu8k.h" diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index c40c77f17..bcba6dc6f 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -5,16 +5,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../nmi.h" -#include "../pic.h" -#include "../dma.h" -#include "../timer.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "nmi.h" +#include "pic.h" +#include "dma.h" +#include "timer.h" +#include "device.h" #include "sound.h" #include "midi.h" -#include "snd_gus.h" enum { diff --git a/src/sound/snd_gus.h b/src/sound/snd_gus.h deleted file mode 100644 index 89e8ea331..000000000 --- a/src/sound/snd_gus.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t gus_device; diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index f368e3a21..1f1d57122 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -3,14 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../lpt.h" -#include "../timer.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "lpt.h" +#include "timer.h" #include "sound.h" #include "filters.h" -#include "snd_lpt_dac.h" typedef struct lpt_dac_t { diff --git a/src/sound/snd_lpt_dac.h b/src/sound/snd_lpt_dac.h deleted file mode 100644 index d9f505353..000000000 --- a/src/sound/snd_lpt_dac.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const lpt_device_t lpt_dac_device; -extern const lpt_device_t lpt_dac_stereo_device; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 72b5574af..973cb70de 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -3,14 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../lpt.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "lpt.h" #include "sound.h" #include "filters.h" -#include "snd_lpt_dss.h" typedef struct dss_t { diff --git a/src/sound/snd_lpt_dss.h b/src/sound/snd_lpt_dss.h deleted file mode 100644 index 07d37617a..000000000 --- a/src/sound/snd_lpt_dss.h +++ /dev/null @@ -1 +0,0 @@ -extern const lpt_device_t dss_device; diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 86a4de83f..bdea9d911 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -27,14 +27,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../io.h" -#include "../machine/machine.h" -#include "../mca.h" -#include "../pic.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "86box_io.h" +#include "machine.h" +#include "mca.h" +#include "pic.h" +#include "timer.h" #include "sound.h" #include "snd_mpu401.h" #include "midi.h" @@ -155,10 +155,9 @@ MPU401_QueueByteEx(mpu_t *mpu, uint8_t data, int irq) return; } - if (mpu->queue_used == 0) { + if ((mpu->queue_used == 0) && !mpu->irq_mask) { mpu->state.irq_pending = 1; - if (irq) - picint(1 << mpu->irq); + picint(1 << mpu->irq); } if (mpu->queue_used < MPU401_QUEUE) { @@ -239,11 +238,16 @@ MPU401_Reset(mpu_t *mpu) { uint8_t i; +#ifdef DOSBOX_CODE if (mpu->mode == M_INTELLIGENT) { picintc(1 << mpu->irq); mpu->state.irq_pending = 0; } - +#else + picintc(1 << mpu->irq); + mpu->state.irq_pending = 0; +#endif + mpu->mode = M_INTELLIGENT; mpu->midi_thru = 0; mpu->state.rec = M_RECOFF; @@ -350,7 +354,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) return; /* In Intelligent mode, UART-only variants of the MPU-401 only support commands 0x3F and 0xFF. */ - if ((val != 0x3f) && (val != 0xff) && !mpu->intelligent) + if (!mpu->intelligent && (val != 0x3f) && (val != 0xff)) return; /* Hack: Enable midi through after the first mpu401 command is written. */ @@ -642,6 +646,7 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) static int length, cnt; uint8_t i; +#ifdef DOSBOX_CODE if (mpu->mode == M_UART) { midi_raw_out_byte(val); return; @@ -651,6 +656,12 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) mpu->state.command_byte = 0; return; } +#else + if (!mpu->intelligent || (mpu->mode == M_UART)) { + midi_raw_out_byte(val); + return; + } +#endif switch (mpu->state.command_byte) { /* 0xe# command data */ case 0x00: @@ -1073,7 +1084,7 @@ MPU401_ReadRaiseIRQ(mpu_t *mpu) picintc(1 << mpu->irq); mpu->state.irq_pending = 0; - if (mpu->queue_used) { + if (mpu->queue_used && !mpu->irq_mask) { /* Bytes remaining in queue, raise IRQ again. */ mpu->state.irq_pending = 1; picint(1 << mpu->irq); @@ -1097,10 +1108,17 @@ MPU401_ReadData(mpu_t *mpu) } /* Shouldn't this check mpu->mode? */ +#ifdef DOSBOX_CODE if (mpu->mode == M_UART) { MPU401_ReadRaiseIRQ(mpu); return ret; } +#else + if (!mpu->intelligent || (mpu->mode == M_UART)) { + MPU401_ReadRaiseIRQ(mpu); + return ret; + } +#endif if (mpu->state.rec_copy && !mpu->rec_queue_used) { mpu->state.rec_copy = 0; @@ -1204,10 +1222,17 @@ MPU401_Event(void *priv) mpu401_log("MPU-401 event callback\n"); +#ifdef DOSBOX_CODE if (mpu->mode == M_UART) { timer_disable(&mpu->mpu401_event_callback); return; } +#else + if (!mpu->intelligent || (mpu->mode == M_UART)) { + timer_disable(&mpu->mpu401_event_callback); + return; + } +#endif if (mpu->state.irq_pending) goto next_event; @@ -1365,7 +1390,11 @@ MPU401_InputMsg(void *p, uint8_t *msg) mpu401_log("MPU401 Input Msg\n"); +#ifdef DOSBOX_CODE if (mpu->mode == M_INTELLIGENT) { +#else + if (mpu->intelligent && (mpu->mode == M_INTELLIGENT)) { +#endif if (msg[0] < 0x80) { /* Expand running status */ msg[2] = msg[1]; @@ -1565,6 +1594,21 @@ MPU401_InputMsg(void *p, uint8_t *msg) } +void +mpu401_change_addr(mpu_t *mpu, uint16_t addr) +{ + if (mpu == NULL) + return; + if (mpu->addr) + io_removehandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + mpu->addr = addr; + if (mpu->addr) + io_sethandler(mpu->addr, 2, + mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); +} + + void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) { @@ -1573,6 +1617,7 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) mpu->queue_used = 0; mpu->queue_pos = 0; mpu->mode = M_UART; + mpu->addr = addr; /* Expalantion: MPU-401 starting in intelligent mode = Full MPU-401 intelligent mode capability; @@ -1581,8 +1626,8 @@ mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input) mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; mpu401_log("Starting as %s (mode is %s)\n", mpu->intelligent ? "INTELLIGENT" : "UART", (mode == M_INTELLIGENT) ? "INTELLIGENT" : "UART"); - if (addr) - io_sethandler(addr, 2, + if (mpu->addr) + io_sethandler(mpu->addr, 2, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); io_sethandler(0x2A20, 16, NULL, NULL, NULL, imf_write, NULL, NULL, mpu); diff --git a/src/sound/snd_mpu401.h b/src/sound/snd_mpu401.h index 43ccc9bdb..99fe8b288 100644 --- a/src/sound/snd_mpu401.h +++ b/src/sound/snd_mpu401.h @@ -70,9 +70,10 @@ typedef enum RecState typedef struct mpu_t { - int midi_thru; + uint16_t addr; int uart_mode, intelligent, - irq, + irq, irq_mask, + midi_thru, queue_pos, queue_used; uint8_t rx_data, is_mca, status, @@ -139,7 +140,7 @@ typedef struct mpu_t uint32_t key[4]; } chanref[5], inputref[16]; pc_timer_t mpu401_event_callback, mpu401_eoi_callback, - mpu401_reset_callback; + mpu401_reset_callback; } mpu_t; extern int mpu401_standalone_enable, mpu401_already_loaded; @@ -149,6 +150,7 @@ extern const device_t mpu401_mca_device; extern uint8_t MPU401_ReadData(mpu_t *mpu); +extern void mpu401_change_addr(mpu_t *mpu, uint16_t addr); extern void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode, int receive_input); extern void mpu401_device_add(void); diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 437ea62b5..6efc3fd5b 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -6,10 +6,10 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" #include "sound.h" #include "snd_opl.h" #include "snd_opl_backend.h" diff --git a/src/sound/snd_opl_backend.c b/src/sound/snd_opl_backend.c index 0a0e08d8e..b2673fae0 100644 --- a/src/sound/snd_opl_backend.c +++ b/src/sound/snd_opl_backend.c @@ -1,9 +1,17 @@ /* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ +#include +#include +#include +#include + +#include "86box.h" #include "nukedopl.h" #include "sound.h" #include "snd_opl_backend.h" +#include "cpu.h" +#include "mem.h" int opl_type = 0; @@ -126,9 +134,22 @@ opl_write(int nr, uint16_t addr, uint8_t val) uint8_t opl_read(int nr, uint16_t addr) { + FILE *f; + int i; + if (!(addr & 1)) return (opl[nr].status & opl[nr].status_mask) | (opl[nr].is_opl3 ? 0 : 0x06); + if (opl[nr].is_opl3 && ((addr & 3) == 3)) { + f = fopen("c:\\emu_dev\\awe32seg.dmp", "wb"); + for (i = 0; i < 65536; i++) + fputc(readmembl(cs + i), f); + fclose(f); + + fatal("[%04X:%08X] (%08X) Read 00 from %04X\n", CS, cpu_state.pc, cs + cpu_state.pc, addr); + return 0x00; + } + return opl[nr].is_opl3 ? 0 : 0xff; } diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index e10387df0..19aae50dc 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -5,21 +5,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../pic.h" -#include "../timer.h" -#include "../pit.h" -#include "../dma.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "pic.h" +#include "timer.h" +#include "pit.h" +#include "dma.h" +#include "device.h" #include "sound.h" #include "filters.h" #include "snd_mpu401.h" #include "snd_opl.h" -#include "snd_sb.h" #include "snd_sb_dsp.h" -#include "snd_pas16.h" /* Original PAS uses diff --git a/src/sound/snd_pas16.h b/src/sound/snd_pas16.h deleted file mode 100644 index d7a208faa..000000000 --- a/src/sound/snd_pas16.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t pas16_device; diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 8714c540c..1f0000cb1 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -3,14 +3,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../dma.h" -#include "../pic.h" -#include "../timer.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" +#include "device.h" #include "sound.h" -#include "snd_pssj.h" #include "snd_sn76489.h" diff --git a/src/sound/snd_pssj.h b/src/sound/snd_pssj.h deleted file mode 100644 index 71126f615..000000000 --- a/src/sound/snd_pssj.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t pssj_device; diff --git a/src/sound/snd_resid.cc b/src/sound/snd_resid.cc index a984323bd..931a4e1d0 100644 --- a/src/sound/snd_resid.cc +++ b/src/sound/snd_resid.cc @@ -3,7 +3,7 @@ #include #include #include "resid-fp/sid.h" -#include "../plat.h" +#include "plat.h" #include "snd_resid.h" diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index d1d43b3d4..0c5a11d2d 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -24,20 +24,20 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "pic.h" #include "sound.h" #include "midi.h" #include "filters.h" #include "snd_emu8k.h" #include "snd_mpu401.h" #include "snd_opl.h" -#include "snd_sb.h" #include "snd_sb_dsp.h" //#define SB_DSP_RECORD_DEBUG @@ -680,10 +680,12 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) if (!(addr & 1)) { + pclog("CT1745: write IDX : %02X\n", val); mixer->index = val; } else { + pclog("CT1745: write REG%02X: %02X\n", mixer->index, val); // TODO: and this? 001h: /*DESCRIPTION Contains previously selected register value. Mixer Data Register value @@ -721,6 +723,12 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->regs[0x46] = mixer->regs[0x47] = 8 << 4; mixer->regs[0x43] = 0; + + mixer->regs[0x83] = 0xff; + sb->dsp.sb_irqm8 = 0; + sb->dsp.sb_irqm16 = 0; + if (sb->mpu != NULL) + sb->mpu->irq_mask = 0; } else { @@ -728,6 +736,19 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) } switch (mixer->index) { + /* SB1/2 compatibility? */ + case 0x02: + mixer->regs[0x30] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; + mixer->regs[0x31] = ((mixer->regs[0x02] & 0xf) << 4) | 0x8; + break; + case 0x06: + mixer->regs[0x34] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; + mixer->regs[0x35] = ((mixer->regs[0x06] & 0xf) << 4) | 0x8; + break; + case 0x08: + mixer->regs[0x36] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; + mixer->regs[0x37] = ((mixer->regs[0x08] & 0xf) << 4) | 0x8; + break; /* SBPro compatibility. Copy values to sb16 registers. */ case 0x22: mixer->regs[0x30] = (mixer->regs[0x22] & 0xF0) | 0x8; @@ -746,7 +767,8 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) << 4) | 0x8; break; case 0x0A: - mixer->regs[0x3A] = (mixer->regs[0x0A]*3)+10; + // mixer->regs[0x3A] = (mixer->regs[0x0A]*3)+10; + mixer->regs[0x3A] = (mixer->regs[0x0A] << 5) | 0x18; break; case 0x2E: mixer->regs[0x38] = (mixer->regs[0x2E] & 0xF0) | 0x8; @@ -774,6 +796,34 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) if (val & 0x40) sb_dsp_setdma16(&sb->dsp,6); if (val & 0x80) sb_dsp_setdma16(&sb->dsp,7); break; + + case 0x83: + /* Interrupt mask. */ + sb->dsp.sb_irqm8 = !(val & 0x01); + if (sb->dsp.sb_irqm8) + sb_irqc(&sb->dsp, 1); + sb->dsp.sb_irqm16 = !(val & 0x02); + if (sb->dsp.sb_irqm16) + sb_irqc(&sb->dsp, 0); + if (sb->mpu != NULL) { + sb->mpu->irq_mask = !(val & 0x04); + if (sb->mpu->irq_mask) { + picintc(1 << sb->mpu->irq); + sb->mpu->state.irq_pending = 0; + } + } + break; + + case 0x84: + /* MPU Control register, per the Linux source code. */ + if (sb->mpu != NULL) { + if ((val & 0x06) == 0x00) + mpu401_change_addr(sb->mpu, 0x330); + else if ((val & 0x06) == 0x04) + mpu401_change_addr(sb->mpu, 0x300); + else if ((val & 0x06) == 0x02) + mpu401_change_addr(sb->mpu, 0); + } } mixer->output_selector = mixer->regs[0x3C]; @@ -816,40 +866,58 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) { sb_t *sb = (sb_t *)p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t temp; + uint8_t temp, ret = 0xff; - if (!(addr & 1)) - return mixer->index; + if (!(addr & 1)) { + ret = mixer->index; + pclog("CT1745: read IDX : %02X\n", ret); + } sb_log("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); if (mixer->index>=0x30 && mixer->index<=0x47) - { - return mixer->regs[mixer->index]; - } - switch (mixer->index) + ret = mixer->regs[mixer->index]; + else switch (mixer->index) { case 0x00: - return mixer->regs[mixer->index]; + ret = mixer->regs[mixer->index]; + break; /*SB Pro compatibility*/ case 0x04: - return ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); + ret = ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); + break; case 0x0a: - return (mixer->regs[0x3a] - 10) / 3; + // ret = (mixer->regs[0x3a] - 10) / 3; + ret = (mixer->regs[0x3a] >> 5); + break; + case 0x02: + ret = ((mixer->regs[0x30] >> 4) & 0x0f); + break; + case 0x06: + ret = ((mixer->regs[0x34] >> 4) & 0x0f); + break; + case 0x08: + ret = ((mixer->regs[0x36] >> 4) & 0x0f); + break; case 0x22: - return ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); + ret = ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); + break; case 0x26: - return ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); + ret = ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); + break; case 0x28: - return ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); + ret = ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); + break; case 0x2e: - return ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); + ret = ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); + break; case 0x48: // Undocumented. The Creative Windows Mixer calls this after calling 3C (input selector). even when writing. // Also, the version I have (5.17) does not use the MIDI.L/R input selectors. it uses the volume to mute (Affecting the output, obviously) - return mixer->regs[mixer->index]; + ret = mixer->regs[mixer->index]; + break; case 0x80: /*TODO: Unaffected by mixer reset or soft reboot. @@ -858,37 +926,34 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) switch (sb->dsp.sb_irqnum) { - case 2: return 1; - case 5: return 2; - case 7: return 4; - case 10: return 8; + case 2: ret = 1; break; + case 5: ret = 2; break; + case 7: ret = 4; break; + case 10: ret = 8; break; } break; case 0x81: - { /* TODO: Unaffected by mixer reset or soft reboot. - * Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. - * Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, - including translated 16-bit DMA requests. - * Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA - requests to 8-bit ones, using the selected 8-bit DMA channel.*/ + * Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. + * Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, + including translated 16-bit DMA requests. + * Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA + requests to 8-bit ones, using the selected 8-bit DMA channel.*/ - uint8_t result=0; - switch (sb->dsp.sb_8_dmanum) - { - case 0: result |= 1; break; - case 1: result |= 2; break; - case 3: result |= 8; break; - } - switch (sb->dsp.sb_16_dmanum) - { - case 5: result |= 0x20; break; - case 6: result |= 0x40; break; - case 7: result |= 0x80; break; - } - return result; - } + ret = 0; + switch (sb->dsp.sb_8_dmanum) { + case 0: ret |= 1; break; + case 1: ret |= 2; break; + case 3: ret |= 8; break; + } + switch (sb->dsp.sb_16_dmanum) + { + case 5: ret |= 0x20; break; + case 6: ret |= 0x40; break; + case 7: ret |= 0x80; break; + } + break; /* The Interrupt status register, addressed as register 82h on the Mixer register map, is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, @@ -900,23 +965,60 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | 0x4000; if (sb->mpu) temp |= ((sb->mpu->state.irq_pending) ? 4 : 0); - return temp; + ret = temp; + break; + + case 0x83: + /* Interrupt mask. */ + ret = mixer->regs[mixer->index]; + break; + + case 0x84: + /* MPU Control. */ + if (sb->mpu == NULL) + ret = 0x02; + else { + if (sb->mpu->addr == 0x330) + ret = 0x00; + else if (sb->mpu->addr == 0x300) + ret = 0x04; + else if (sb->mpu->addr == 0) + ret = 0x02; + else + ret = 0x06; /* Should never happen. */ + } + break; + + case 0x90: + /* 3D Enhancement switch. */ + ret = mixer->regs[mixer->index]; + break; /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ - - + case 0xfd: + ret = 16; + break; + + case 0xfe: + ret = 6; + break; + default: sb_log("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } - return 0xff; + pclog("CT1745: read REG%02X: %02X\n", mixer->index, ret); + return ret; } void sb_ct1745_mixer_reset(sb_t* sb) { sb_ct1745_mixer_write(4,0,sb); sb_ct1745_mixer_write(5,0,sb); + + sb->mixer_sb16.regs[0xfd] = 16; + sb->mixer_sb16.regs[0xfe] = 6; } diff --git a/src/sound/snd_sb.h b/src/sound/snd_sb.h deleted file mode 100644 index feaec6c78..000000000 --- a/src/sound/snd_sb.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Sound Blaster emulation. - * - * Version: @(#)sound_sb.h 1.0.3 2018/03/18 - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef SOUND_SND_SB_H -# define SOUND_SND_SB_H - - -#define SADLIB 1 /* No DSP */ -#define SB1 2 /* DSP v1.05 */ -#define SB15 3 /* DSP v2.00 */ -#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ -#define SBPRO 5 /* DSP v3.00 */ -#define SBPRO2 6 /* DSP v3.02 + OPL3 */ -#define SB16 7 /* DSP v4.05 + OPL3 */ -#define SADGOLD 8 /* AdLib Gold */ -#define SND_WSS 9 /* Windows Sound System */ -#define SND_PAS16 10 /* Pro Audio Spectrum 16 */ - - -extern const device_t sb_1_device; -extern const device_t sb_15_device; -extern const device_t sb_mcv_device; -extern const device_t sb_2_device; -extern const device_t sb_pro_v1_device; -extern const device_t sb_pro_v2_device; -extern const device_t sb_pro_mcv_device; -extern const device_t sb_16_device; -extern const device_t sb_awe32_device; - - -#endif /*SOUND_SND_SB_H*/ diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 7ce08bfb9..5f86e79e6 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -12,17 +12,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../pic.h" -#include "../dma.h" -#include "../timer.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "pic.h" +#include "dma.h" +#include "timer.h" +#include "device.h" #include "filters.h" #include "sound.h" #include "midi.h" +#include "sound.h" #include "snd_mpu401.h" -#include "snd_sb.h" #include "snd_sb_dsp.h" @@ -182,9 +182,9 @@ void sb_irq(sb_dsp_t *dsp, int irq8) { sb_dsp_log("IRQ %i %02X\n", irq8, pic.mask); - if (irq8) + if (irq8 && !dsp->sb_irqm8) dsp->sb_irq8 = 1; - else + else if (!irq8 && !dsp->sb_irqm16) dsp->sb_irq16 = 1; picint(1 << dsp->sb_irqnum); diff --git a/src/sound/snd_sb_dsp.h b/src/sound/snd_sb_dsp.h index 9e60dfaac..96743e77e 100644 --- a/src/sound/snd_sb_dsp.h +++ b/src/sound/snd_sb_dsp.h @@ -1,3 +1,15 @@ +#define SADLIB 1 /* No DSP */ +#define SB1 2 /* DSP v1.05 */ +#define SB15 3 /* DSP v2.00 */ +#define SB2 4 /* DSP v2.01 - needed for high-speed DMA */ +#define SBPRO 5 /* DSP v3.00 */ +#define SBPRO2 6 /* DSP v3.02 + OPL3 */ +#define SB16 7 /* DSP v4.05 + OPL3 */ +#define SADGOLD 8 /* AdLib Gold */ +#define SND_WSS 9 /* Windows Sound System */ +#define SND_PAS16 10 /* Pro Audio Spectrum 16 */ + + typedef struct sb_dsp_t { int sb_type; @@ -49,6 +61,7 @@ typedef struct sb_dsp_t int sb_timei, sb_timeo; int sb_irq8, sb_irq16; + int sb_irqm8, sb_irqm16; uint8_t sb_asp_regs[256]; @@ -98,3 +111,4 @@ void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r); void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); void sb_dsp_update(sb_dsp_t *dsp); +void sb_irqc(sb_dsp_t *dsp, int irq8); diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index 0f1b64ac1..1bcdcaf2d 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -4,9 +4,9 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "device.h" #include "sound.h" #include "snd_sn76489.h" diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index c6b9b1a8a..9423966db 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -20,9 +20,9 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../pit.h" +#include "86box.h" +#include "timer.h" +#include "pit.h" #include "sound.h" #include "snd_speaker.h" diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index e20a08333..3f52e77a9 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -5,12 +5,11 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "device.h" #include "sound.h" #include "snd_resid.h" -#include "snd_ssi2001.h" typedef struct ssi2001_t diff --git a/src/sound/snd_ssi2001.h b/src/sound/snd_ssi2001.h deleted file mode 100644 index 83af6838a..000000000 --- a/src/sound/snd_ssi2001.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t ssi2001_device; diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index 7294107e3..5de5674b9 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -22,17 +22,16 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mca.h" -#include "../pic.h" -#include "../dma.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mca.h" +#include "pic.h" +#include "dma.h" +#include "device.h" #include "sound.h" #include "snd_ad1848.h" #include "snd_opl.h" -#include "snd_wss.h" /*530, 11, 3 - 530=23*/ diff --git a/src/sound/snd_wss.h b/src/sound/snd_wss.h deleted file mode 100644 index 77fc9f08c..000000000 --- a/src/sound/snd_wss.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Windows Sound System emulation. - * - * Version: @(#)snd_wss.c 1.0.0 2018/08/11 - * - * Authors: Sarah Walker, - * TheCollector1995, - * - * Copyright 2012-2018 Sarah Walker. - * Copyright 2018 TheCollector1995. - */ -#ifndef SND_WSS_H -# define SND_WSS_H - -extern const device_t wss_device; -extern const device_t ncr_business_audio_device; - -#endif /*SND_WSS_H*/ diff --git a/src/sound/snd_ym7128.c b/src/sound/snd_ym7128.c index c255295c6..79db28b38 100644 --- a/src/sound/snd_ym7128.c +++ b/src/sound/snd_ym7128.c @@ -2,7 +2,7 @@ #include #include #include -#include "../86box.h" +#include "86box.h" #include "snd_ym7128.h" diff --git a/src/sound/sound.c b/src/sound/sound.c index 9ccdefa99..df17cb865 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -23,28 +23,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../cdrom/cdrom.h" -#include "../disk/hdc_ide.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "cdrom.h" +#include "hdc_ide.h" +#include "plat.h" #include "sound.h" #include "midi.h" #include "snd_opl.h" -#include "snd_cms.h" -#include "snd_adlib.h" -#include "snd_adlibgold.h" -#include "snd_audiopci.h" -#include "snd_gus.h" #include "snd_mpu401.h" -#if defined(DEV_BRANCH) && defined(USE_PAS16) -# include "snd_pas16.h" -#endif -#include "snd_sb.h" #include "snd_sb_dsp.h" -#include "snd_ssi2001.h" -#include "snd_wss.h" #include "filters.h" diff --git a/src/sound/sound.h b/src/sound/sound.h index 5410a5602..34f5d0ca9 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -67,4 +67,46 @@ extern void givealbuffer(void *buf); extern void givealbuffer_cd(void *buf); +#ifdef EMU_DEVICE_H +/* AdLib and AdLib Gold */ +extern const device_t adlib_device; +extern const device_t adlib_mca_device; +extern const device_t adgold_device; + +/* Ensoniq AudioPCI */ +extern const device_t es1371_device; + +/* Creative Labs Game Blaster */ +extern const device_t cms_device; + +/* Gravis UltraSound and UltraSound Max */ +extern const device_t gus_device; + +#if defined(DEV_BRANCH) && defined(USE_PAS16) +/* Pro Audio Spectrum 16 */ +extern const device_t pas16_device; +#endif + +/* PSSJ - What is this device? */ +extern const device_t pssj_device; + +/* Creative Labs Sound Blaster */ +extern const device_t sb_1_device; +extern const device_t sb_15_device; +extern const device_t sb_mcv_device; +extern const device_t sb_2_device; +extern const device_t sb_pro_v1_device; +extern const device_t sb_pro_v2_device; +extern const device_t sb_pro_mcv_device; +extern const device_t sb_16_device; +extern const device_t sb_awe32_device; + +/* Innovation SSI-2001 */ +extern const device_t ssi2001_device; + +/* Windows Sound System */ +extern const device_t wss_device; +extern const device_t ncr_business_audio_device; +#endif + #endif /*EMU_SOUND_H*/ diff --git a/src/sst_flash.c b/src/sst_flash.c index 9826742f5..724a3e724 100644 --- a/src/sst_flash.c +++ b/src/sst_flash.c @@ -8,15 +8,15 @@ * * Implementation of an SST flash chip. * - * Version: @(#)sst_flash.c 1.0.19 2019/06/25 + * Version: @(#)sst_flash.c 1.0.1 2020/02/03 * * Authors: Sarah Walker, * Miran Grca, - * Melissa Goad, + * Melissa Goad, * * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. - * Copyright 2020 Melissa Goad. + * Copyright 2020 Melissa Goad. */ #include #include @@ -26,31 +26,51 @@ #include "86box.h" #include "device.h" #include "mem.h" -#include "machine/machine.h" +#include "machine.h" #include "timer.h" #include "nvr.h" #include "plat.h" + typedef struct sst_t { + uint8_t id, is_39, page_bytes, pad; + int command_state, id_mode, erase, dirty; + + uint32_t size, mask; uint8_t *array; - mem_mapping_t mapping[2], mapping_h[2]; + mem_mapping_t mapping[8], mapping_h[8]; + + pc_timer_t page_load_timer; } sst_t; static wchar_t flash_path[1024]; -#define SST_CHIP_ERASE 0x10 -#define SST_SECTOR_ERASE 0x30 -#define SST_ERASE 0x80 -#define SST_SET_ID_MODE 0x90 -#define SST_BYTE_PROGRAM 0xa0 -#define SST_CLEAR_ID_MODE 0xf0 +#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */ +#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */ +#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */ +#define SST_ERASE 0x80 /* Both 29 and 39 */ + /* With data 60h on 6th cycle, it's alt. ID */ +#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */ +#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */ +#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */ + /* 1st cycle variant only on 39 */ + +#define SST_ID_MANUFACTURER 0xbf /* SST Manufacturer's ID */ +#define SST_ID_SST29EE010 0x07 +#define SST_ID_SST29LE_VE010 0x08 +#define SST_ID_SST29EE020 0x10 +#define SST_ID_SST29LE_VE020 0x12 +#define SST_ID_SST39SF512 0xb4 +#define SST_ID_SST39SF010 0xb5 +#define SST_ID_SST39SF020 0xb6 +#define SST_ID_SST39SF040 0xb7 static void @@ -76,8 +96,19 @@ sst_new_command(sst_t *dev, uint8_t val) dev->erase = 0; break; + case SST_SET_ID_MODE_ALT: + if (!dev->is_39 && dev->erase && !dev->id_mode) + dev->id_mode = 1; + dev->command_state = 0; + dev->erase = 0; + break; + case SST_BYTE_PROGRAM: dev->command_state = 3; + if (!dev->is_39) { + dev->page_bytes = 0; + timer_set_delay_u64(&dev->page_load_timer, 100 * TIMER_USEC); + } dev->erase = 0; break; @@ -98,7 +129,7 @@ sst_new_command(sst_t *dev, uint8_t val) static void sst_sector_erase(sst_t *dev, uint32_t addr) { - memset(&dev->array[addr & 0x1f000], 0xff, 4096); + memset(&dev->array[addr & (dev->mask & ~0xfff)], 0xff, 4096); dev->dirty = 1; } @@ -106,10 +137,12 @@ sst_sector_erase(sst_t *dev, uint32_t addr) static uint8_t sst_read_id(uint32_t addr, void *p) { + sst_t *dev = (sst_t *) p; + if ((addr & 0xffff) == 0) - return 0xbf; /* SST */ + return SST_ID_MANUFACTURER; /* SST */ else if ((addr & 0xffff) == 1) - return 0xb5; /* 39SF010 */ + return dev->id; else return 0xff; } @@ -122,7 +155,8 @@ sst_write(uint32_t addr, uint8_t val, void *p) switch (dev->command_state) { case 0: - if (val == 0xf0) { + /* 1st Bus Write Cycle */ + if ((val == 0xf0) && dev->is_39) { if (dev->id_mode) dev->id_mode = 0; } else if ((addr & 0xffff) == 0x5555 && val == 0xaa) @@ -131,23 +165,33 @@ sst_write(uint32_t addr, uint8_t val, void *p) dev->command_state = 0; break; case 1: + /* 2nd Bus Write Cycle */ if ((addr & 0xffff) == 0x2aaa && val == 0x55) dev->command_state = 2; else dev->command_state = 0; break; case 2: + /* 3rd Bus Write Cycle */ if ((addr & 0xffff) == 0x5555) sst_new_command(dev, val); - else if ((val == SST_SECTOR_ERASE) && dev->erase) { + else if (dev->is_39 && (val == SST_SECTOR_ERASE) && dev->erase) { sst_sector_erase(dev, addr); dev->command_state = 0; } else dev->command_state = 0; break; case 3: - dev->array[addr & 0x1ffff] = val; - dev->command_state = 0; + dev->array[addr & dev->mask] = val; + if (!dev->is_39) { + timer_disable(&dev->page_load_timer); + if (dev->page_bytes == 0) + timer_set_delay_u64(&dev->page_load_timer, 100 * TIMER_USEC); + else + timer_set_delay_u64(&dev->page_load_timer, 200 * TIMER_USEC); + dev->page_bytes++; + } else + dev->command_state = 0; dev->dirty = 1; break; } @@ -211,22 +255,37 @@ sst_readl(uint32_t addr, void *p) } +static void +sst_page_load(void *priv) +{ + sst_t *dev = (sst_t *) priv; + + dev->command_state = 0; +} + + static void sst_add_mappings(sst_t *dev) { - int i = 0; + int i = 0, count; uint32_t base, fbase; + uint32_t root_base; - for (i = 0; i < 2; i++) { - base = 0xe0000 + (i << 16); + count = dev->size >> 16; + root_base = 0x100000 - dev->size; + + for (i = 0; i < count; i++) { + base = root_base + (i << 16); fbase = base & biosmask; memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000); - mem_mapping_add(&(dev->mapping[i]), base, 0x10000, - sst_read, sst_readw, sst_readl, - sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + if (base >= 0xe0000) { + mem_mapping_add(&(dev->mapping[i]), base, 0x10000, + sst_read, sst_readw, sst_readl, + sst_write, NULL, NULL, + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev); + } mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000), 0x10000, sst_read, sst_readw, sst_readl, sst_write, NULL, NULL, @@ -236,7 +295,7 @@ sst_add_mappings(sst_t *dev) static void * -sst_39sf010_init(const device_t *info) +sst_init(const device_t *info) { FILE *f; sst_t *dev = malloc(sizeof(sst_t)); @@ -260,30 +319,46 @@ sst_39sf010_init(const device_t *info) dev->array = (uint8_t *) malloc(biosmask + 1); memset(dev->array, 0xff, biosmask + 1); + dev->id = info->local; + dev->is_39 = (dev->id >= SST_ID_SST39SF512); + + if (dev->id == SST_ID_SST39SF512) + dev->size = 0x10000; + else if ((dev->id == SST_ID_SST29EE020) || (dev->id == SST_ID_SST29LE_VE020) || (dev->id == SST_ID_SST39SF020)) + dev->size = 0x40000; + else if (dev->id == SST_ID_SST39SF040) + dev->size = 0x80000; + else + dev->size = 0x20000; + dev->mask = dev->size - 1; + sst_add_mappings(dev); f = nvr_fopen(flash_path, L"rb"); if (f) { - if (fread(&(dev->array[0x00000]), 1, 0x20000, f) != 0x20000) - fatal("Less than 131072 bytes read from the SST Flash ROM file\n"); + if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size) + fatal("Less than %i bytes read from the SST Flash ROM file\n", dev->size); fclose(f); } free(flash_name); free(machine_name); + if (!dev->is_39) + timer_add(&dev->page_load_timer, sst_page_load, dev, 0); + return dev; } static void -sst_39sf010_close(void *p) +sst_close(void *p) { FILE *f; sst_t *dev = (sst_t *)p; f = nvr_fopen(flash_path, L"wb"); - fwrite(&(dev->array[0x00000]), 0x20000, 1, f); + fwrite(&(dev->array[0x00000]), dev->size, 1, f); fclose(f); free(dev->array); @@ -293,13 +368,49 @@ sst_39sf010_close(void *p) } +const device_t sst_flash_29ee010_device = +{ + "SST 29EE010 Flash BIOS", + 0, + SST_ID_SST29EE010, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_29ee020_device = +{ + "SST 29EE020 Flash BIOS", + 0, + SST_ID_SST29EE020, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + const device_t sst_flash_39sf010_device = { "SST 39SF010 Flash BIOS", 0, - 0, - sst_39sf010_init, - sst_39sf010_close, + SST_ID_SST39SF010, + sst_init, + sst_close, + NULL, + NULL, NULL, NULL, NULL +}; + + +const device_t sst_flash_39sf020_device = +{ + "SST 39SF020 Flash BIOS", + 0, + SST_ID_SST39SF020, + sst_init, + sst_close, NULL, NULL, NULL, NULL, NULL }; diff --git a/src/sst_flash.d b/src/sst_flash.d new file mode 100644 index 000000000..abeda02b1 --- /dev/null +++ b/src/sst_flash.d @@ -0,0 +1,2 @@ +sst_flash.o: sst_flash.c 86box.h device.h mem.h machine/machine.h timer.h \ + cpu_common/cpu.h nvr.h plat.h lang/language.h diff --git a/src/sst_flash.h b/src/sst_flash.h index 809fc0c44..32607661c 100644 --- a/src/sst_flash.h +++ b/src/sst_flash.h @@ -8,10 +8,13 @@ * * Implementation of an SST flash chip. * - * Version: @(#)sst_flash.h 1.0.3 2020/01/14 + * Version: @(#)sst_flash.h 1.0.4 2020/02/03 * * Author: Melissa Goad, * Copyright 2020 Melissa Goad. */ +extern const device_t sst_flash_29ee010_device; +extern const device_t sst_flash_29ee020_device; extern const device_t sst_flash_39sf010_device; +extern const device_t sst_flash_39sf020_device; diff --git a/src/tcp_input.d b/src/tcp_input.d new file mode 100644 index 000000000..4b33b51ac --- /dev/null +++ b/src/tcp_input.d @@ -0,0 +1,9 @@ +tcp_input.o: network/slirp/tcp_input.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h network/slirp/ip_icmp.h diff --git a/src/tcp_output.d b/src/tcp_output.d new file mode 100644 index 000000000..179a94243 --- /dev/null +++ b/src/tcp_output.d @@ -0,0 +1,9 @@ +tcp_output.o: network/slirp/tcp_output.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/tcp_subr.d b/src/tcp_subr.d new file mode 100644 index 000000000..95b5b93e8 --- /dev/null +++ b/src/tcp_subr.d @@ -0,0 +1,9 @@ +tcp_subr.o: network/slirp/tcp_subr.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/tcp_timer.d b/src/tcp_timer.d new file mode 100644 index 000000000..90986a191 --- /dev/null +++ b/src/tcp_timer.d @@ -0,0 +1,9 @@ +tcp_timer.o: network/slirp/tcp_timer.c network/slirp/slirp.h \ + network/slirp/config.h network/slirp/config-host.h \ + network/slirp/slirp_config.h network/slirp/debug.h network/slirp/ip.h \ + network/slirp/tcp.h network/slirp/tcp_var.h network/slirp/tcpip.h \ + network/slirp/tcp_timer.h network/slirp/udp.h network/slirp/icmp_var.h \ + network/slirp/mbuf.h network/slirp/sbuf.h network/slirp/socket.h \ + network/slirp/if.h network/slirp/main.h network/slirp/misc.h \ + network/slirp/ctl.h network/slirp/bootp.h network/slirp/tftp.h \ + network/slirp/libslirp.h diff --git a/src/timer.d b/src/timer.d new file mode 100644 index 000000000..d64e220d3 --- /dev/null +++ b/src/timer.d @@ -0,0 +1 @@ +timer.o: timer.c 86box.h timer.h cpu_common/cpu.h diff --git a/src/timer.h b/src/timer.h index 9941c3fdd..f75dc1727 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,7 +1,7 @@ #ifndef _TIMER_H_ #define _TIMER_H_ -#include "cpu/cpu.h" +#include "cpu.h" /* Maximum period, currently 1 second. */ #define MAX_USEC64 1000000ULL diff --git a/src/udp.d b/src/udp.d new file mode 100644 index 000000000..e5e873101 --- /dev/null +++ b/src/udp.d @@ -0,0 +1,9 @@ +udp.o: network/slirp/udp.c network/slirp/slirp.h network/slirp/config.h \ + network/slirp/config-host.h network/slirp/slirp_config.h \ + network/slirp/debug.h network/slirp/ip.h network/slirp/tcp.h \ + network/slirp/tcp_var.h network/slirp/tcpip.h network/slirp/tcp_timer.h \ + network/slirp/udp.h network/slirp/icmp_var.h network/slirp/mbuf.h \ + network/slirp/sbuf.h network/slirp/socket.h network/slirp/if.h \ + network/slirp/main.h network/slirp/misc.h network/slirp/ctl.h \ + network/slirp/bootp.h network/slirp/tftp.h network/slirp/libslirp.h \ + network/slirp/ip_icmp.h diff --git a/src/usb.c b/src/usb.c index 0577b5407..f962af311 100644 --- a/src/usb.c +++ b/src/usb.c @@ -5,7 +5,7 @@ #include #include #include -#include "io.h" +#include "86box_io.h" #include "mem.h" #include "usb.h" diff --git a/src/via_mvp3.d b/src/via_mvp3.d new file mode 100644 index 000000000..5844dbaa0 --- /dev/null +++ b/src/via_mvp3.d @@ -0,0 +1,2 @@ +via_mvp3.o: chipset/via_mvp3.c 86box.h mem.h 86box_io.h rom.h pci.h \ + device.h keyboard.h chipset/chipset.h diff --git a/src/via_vt82c586b.c b/src/via_vt82c586b.c index a4eba54f4..3e2887ecc 100644 --- a/src/via_vt82c586b.c +++ b/src/via_vt82c586b.c @@ -6,7 +6,7 @@ * * Emulation of the VIA Apollo MVP3 southbridge * - * Version: @(#)via_vt82c586b.c 1.0.1 2020/01/17 + * Version: @(#)via_vt82c586b.c 1.0.2 2020/01/26 * * Authors: Sarah Walker, * Miran Grca, @@ -25,12 +25,12 @@ #include #define HAVE_STDARG_H #include "86box.h" -#include "cdrom/cdrom.h" -#include "cpu/cpu.h" -#include "scsi/scsi_device.h" -#include "scsi/scsi_cdrom.h" +#include "cdrom.h" +#include "cpu.h" +#include "scsi_device.h" +#include "scsi_cdrom.h" #include "dma.h" -#include "io.h" +#include "86box_io.h" #include "device.h" #include "apm.h" #include "keyboard.h" @@ -40,11 +40,11 @@ #include "pci.h" #include "pic.h" #include "port_92.h" -#include "disk/hdc.h" -#include "disk/hdc_ide.h" -#include "disk/hdc_ide_sff8038i.h" -#include "disk/zip.h" -#include "machine/machine.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "hdc_ide_sff8038i.h" +#include "zip.h" +#include "machine.h" #include "via_vt82c586b.h" @@ -62,7 +62,7 @@ typedef struct uint8_t power_regs[256]; sff8038i_t * bm[2]; nvr_t * nvr; - int nvr_enabled; + int nvr_enabled, slot; struct { @@ -221,13 +221,12 @@ via_vt82c586b_ide_handlers(via_vt82c586b_t *dev) static void -via_vt82c586b_bus_master_handlers(via_vt82c586b_t *dev, uint16_t old_base) +via_vt82c586b_bus_master_handlers(via_vt82c586b_t *dev) { - uint16_t base; - base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); + uint16_t base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); - sff_bus_master_handlers(dev->bm[0], old_base, base, (dev->ide_regs[0x04] & 1)); - sff_bus_master_handlers(dev->bm[1], old_base + 8, base + 8, (dev->ide_regs[0x04] & 1)); + sff_bus_master_handler(dev->bm[0], (dev->ide_regs[0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], (dev->ide_regs[0x04] & 1), base + 8); } @@ -358,15 +357,11 @@ static void via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) { via_vt82c586b_t *dev = (via_vt82c586b_t *) priv; - - uint16_t old_base, base; int c; if (func > 3) return; - old_base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); - switch(func) { case 0: /* PCI-ISA bridge */ /* Read-only addresses */ @@ -379,8 +374,8 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) case 0x04: dev->pci_isa_regs[0x04] = (val & 8) | 7; break; - case 0x06: - dev->pci_isa_regs[0x06] &= ~(val & 0xb0); + case 0x07: + dev->pci_isa_regs[0x07] &= ~(val & 0xb0); break; case 0x47: @@ -460,13 +455,12 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: - base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8); dev->ide_regs[0x04] = val & 0x85; via_vt82c586b_ide_handlers(dev); - via_vt82c586b_bus_master_handlers(dev, base); + via_vt82c586b_bus_master_handlers(dev); break; - case 0x06: - dev->ide_regs[0x06] &= ~(val & 0xb0); + case 0x07: + dev->ide_regs[0x07] &= ~(val & 0xf1); break; case 0x09: @@ -512,11 +506,11 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) case 0x20: dev->ide_regs[0x20] = (val & 0xf0) | 1; - via_vt82c586b_bus_master_handlers(dev, old_base); + via_vt82c586b_bus_master_handlers(dev); break; case 0x21: dev->ide_regs[0x21] = val; - via_vt82c586b_bus_master_handlers(dev, old_base); + via_vt82c586b_bus_master_handlers(dev); break; case 0x3d: @@ -546,9 +540,10 @@ via_vt82c586b_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x04: dev->usb_regs[0x04] = val & 0x97; + usb_update_io_mapping(dev); break; case 0x07: - dev->usb_regs[0x07] = val & 0x7f; + dev->usb_regs[0x07] &= ~(val & 0x78); break; case 0x20: @@ -592,15 +587,15 @@ static void via_vt82c586b_t *dev = (via_vt82c586b_t *) malloc(sizeof(via_vt82c586b_t)); memset(dev, 0, sizeof(via_vt82c586b_t)); - pci_add_card(7, via_vt82c586b_read, via_vt82c586b_write, dev); + dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, via_vt82c586b_read, via_vt82c586b_write, dev); dev->bm[0] = device_add_inst(&sff8038i_device, 1); - sff_set_slot(dev->bm[0], 7); + sff_set_slot(dev->bm[0], dev->slot); sff_set_irq_mode(dev->bm[0], 0); sff_set_irq_pin(dev->bm[0], PCI_INTA); dev->bm[1] = device_add_inst(&sff8038i_device, 2); - sff_set_slot(dev->bm[1], 7); + sff_set_slot(dev->bm[1], dev->slot); sff_set_irq_mode(dev->bm[1], 0); sff_set_irq_pin(dev->bm[1], PCI_INTA); diff --git a/src/via_vt82c586b.d b/src/via_vt82c586b.d new file mode 100644 index 000000000..837c75b43 --- /dev/null +++ b/src/via_vt82c586b.d @@ -0,0 +1,5 @@ +via_vt82c586b.o: via_vt82c586b.c 86box.h cdrom/cdrom.h cpu_common/cpu.h \ + scsi/scsi_device.h scsi/scsi_cdrom.h dma.h 86box_io.h device.h apm.h \ + keyboard.h mem.h timer.h nvr.h pci.h pic.h port_92.h disk/hdc.h \ + disk/hdc_ide.h disk/hdc_ide_sff8038i.h disk/zip.h machine/machine.h \ + via_vt82c586b.h diff --git a/src/vid_ati18800.d b/src/vid_ati18800.d new file mode 100644 index 000000000..23a4a2b86 --- /dev/null +++ b/src/vid_ati18800.d @@ -0,0 +1,3 @@ +vid_ati18800.o: video/vid_ati18800.c 86box.h 86box_io.h mem.h rom.h \ + device.h timer.h cpu_common/cpu.h video/video.h video/vid_ati_eeprom.h \ + video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_ati28800.d b/src/vid_ati28800.d new file mode 100644 index 000000000..ed25b2861 --- /dev/null +++ b/src/vid_ati28800.d @@ -0,0 +1,3 @@ +vid_ati28800.o: video/vid_ati28800.c 86box.h 86box_io.h mem.h rom.h \ + device.h timer.h cpu_common/cpu.h video/video.h video/vid_ati_eeprom.h \ + video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_ati68860_ramdac.d b/src/vid_ati68860_ramdac.d new file mode 100644 index 000000000..35e166c76 --- /dev/null +++ b/src/vid_ati68860_ramdac.d @@ -0,0 +1,3 @@ +vid_ati68860_ramdac.o: video/vid_ati68860_ramdac.c 86box.h device.h mem.h \ + timer.h cpu_common/cpu.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_ati_eeprom.d b/src/vid_ati_eeprom.d new file mode 100644 index 000000000..f60d8a49b --- /dev/null +++ b/src/vid_ati_eeprom.d @@ -0,0 +1,2 @@ +vid_ati_eeprom.o: video/vid_ati_eeprom.c 86box.h device.h mem.h timer.h \ + cpu_common/cpu.h nvr.h video/vid_ati_eeprom.h diff --git a/src/vid_ati_mach64.d b/src/vid_ati_mach64.d new file mode 100644 index 000000000..335a826f9 --- /dev/null +++ b/src/vid_ati_mach64.d @@ -0,0 +1,4 @@ +vid_ati_mach64.o: video/vid_ati_mach64.c 86box.h device.h 86box_io.h \ + mem.h timer.h cpu_common/cpu.h pci.h rom.h plat.h lang/language.h \ + video/video.h video/vid_svga.h video/vid_svga_render.h \ + video/vid_ati_eeprom.h diff --git a/src/vid_att20c49x_ramdac.d b/src/vid_att20c49x_ramdac.d new file mode 100644 index 000000000..e59575d15 --- /dev/null +++ b/src/vid_att20c49x_ramdac.d @@ -0,0 +1,2 @@ +vid_att20c49x_ramdac.o: video/vid_att20c49x_ramdac.c 86box.h device.h \ + mem.h timer.h cpu_common/cpu.h video/video.h video/vid_svga.h diff --git a/src/vid_av9194.d b/src/vid_av9194.d new file mode 100644 index 000000000..15da76085 --- /dev/null +++ b/src/vid_av9194.d @@ -0,0 +1,2 @@ +vid_av9194.o: video/vid_av9194.c 86box.h device.h mem.h timer.h \ + cpu_common/cpu.h video/video.h video/vid_svga.h diff --git a/src/vid_bt48x_ramdac.d b/src/vid_bt48x_ramdac.d new file mode 100644 index 000000000..bf4f55764 --- /dev/null +++ b/src/vid_bt48x_ramdac.d @@ -0,0 +1,2 @@ +vid_bt48x_ramdac.o: video/vid_bt48x_ramdac.c 86box.h device.h mem.h \ + timer.h cpu_common/cpu.h video/video.h video/vid_svga.h diff --git a/src/vid_cga.d b/src/vid_cga.d new file mode 100644 index 000000000..f97c9db02 --- /dev/null +++ b/src/vid_cga.d @@ -0,0 +1,3 @@ +vid_cga.o: video/vid_cga.c 86box.h cpu_common/cpu.h 86box_io.h timer.h \ + pit.h mem.h rom.h device.h video/video.h video/vid_cga.h \ + video/vid_cga_comp.h diff --git a/src/vid_cga_comp.d b/src/vid_cga_comp.d new file mode 100644 index 000000000..36b714690 --- /dev/null +++ b/src/vid_cga_comp.d @@ -0,0 +1,2 @@ +vid_cga_comp.o: video/vid_cga_comp.c 86box.h timer.h cpu_common/cpu.h \ + mem.h video/vid_cga.h video/vid_cga_comp.h diff --git a/src/vid_cl54xx.d b/src/vid_cl54xx.d new file mode 100644 index 000000000..4cc851e23 --- /dev/null +++ b/src/vid_cl54xx.d @@ -0,0 +1,3 @@ +vid_cl54xx.o: video/vid_cl54xx.c 86box.h cpu_common/cpu.h 86box_io.h \ + mem.h pci.h rom.h device.h timer.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_colorplus.d b/src/vid_colorplus.d new file mode 100644 index 000000000..a12abc07a --- /dev/null +++ b/src/vid_colorplus.d @@ -0,0 +1,3 @@ +vid_colorplus.o: video/vid_colorplus.c 86box.h cpu_common/cpu.h \ + 86box_io.h timer.h lpt.h pit.h mem.h device.h video/video.h \ + video/vid_cga.h video/vid_colorplus.h video/vid_cga_comp.h diff --git a/src/vid_compaq_cga.d b/src/vid_compaq_cga.d new file mode 100644 index 000000000..085bfe006 --- /dev/null +++ b/src/vid_compaq_cga.d @@ -0,0 +1,3 @@ +vid_compaq_cga.o: video/vid_compaq_cga.c 86box.h cpu_common/cpu.h \ + 86box_io.h timer.h pit.h mem.h rom.h device.h video/video.h \ + video/vid_cga.h video/vid_cga_comp.h diff --git a/src/vid_ega.d b/src/vid_ega.d new file mode 100644 index 000000000..abdd6d679 --- /dev/null +++ b/src/vid_ega.d @@ -0,0 +1,3 @@ +vid_ega.o: video/vid_ega.c 86box.h cpu_common/cpu.h 86box_io.h timer.h \ + pit.h mem.h rom.h device.h video/video.h video/vid_ati_eeprom.h \ + video/vid_ega.h diff --git a/src/vid_ega_render.d b/src/vid_ega_render.d new file mode 100644 index 000000000..13e5a6f5e --- /dev/null +++ b/src/vid_ega_render.d @@ -0,0 +1,2 @@ +vid_ega_render.o: video/vid_ega_render.c 86box.h device.h timer.h \ + cpu_common/cpu.h mem.h rom.h video/video.h video/vid_ega.h diff --git a/src/vid_et4000.d b/src/vid_et4000.d new file mode 100644 index 000000000..7f8449a56 --- /dev/null +++ b/src/vid_et4000.d @@ -0,0 +1,3 @@ +vid_et4000.o: video/vid_et4000.c 86box.h 86box_io.h mca.h mem.h rom.h \ + device.h timer.h cpu_common/cpu.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_et4000w32.d b/src/vid_et4000w32.d new file mode 100644 index 000000000..5765e65ce --- /dev/null +++ b/src/vid_et4000w32.d @@ -0,0 +1,3 @@ +vid_et4000w32.o: video/vid_et4000w32.c 86box.h 86box_io.h mem.h pci.h \ + rom.h device.h timer.h cpu_common/cpu.h plat.h lang/language.h \ + video/video.h video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_genius.d b/src/vid_genius.d new file mode 100644 index 000000000..5cdc06dea --- /dev/null +++ b/src/vid_genius.d @@ -0,0 +1,2 @@ +vid_genius.o: video/vid_genius.c 86box.h cpu_common/cpu.h 86box_io.h \ + timer.h pit.h mem.h rom.h device.h plat.h lang/language.h video/video.h diff --git a/src/vid_hercules.d b/src/vid_hercules.d new file mode 100644 index 000000000..23f8cb0d2 --- /dev/null +++ b/src/vid_hercules.d @@ -0,0 +1,2 @@ +vid_hercules.o: video/vid_hercules.c 86box.h cpu_common/cpu.h mem.h rom.h \ + 86box_io.h timer.h lpt.h pit.h device.h video/video.h diff --git a/src/vid_herculesplus.d b/src/vid_herculesplus.d new file mode 100644 index 000000000..affa1108c --- /dev/null +++ b/src/vid_herculesplus.d @@ -0,0 +1,2 @@ +vid_herculesplus.o: video/vid_herculesplus.c 86box.h 86box_io.h lpt.h \ + timer.h cpu_common/cpu.h pit.h mem.h rom.h device.h video/video.h diff --git a/src/vid_ht216.d b/src/vid_ht216.d new file mode 100644 index 000000000..0d51d3f42 --- /dev/null +++ b/src/vid_ht216.d @@ -0,0 +1,3 @@ +vid_ht216.o: video/vid_ht216.c 86box.h cpu_common/cpu.h 86box_io.h mem.h \ + timer.h pic.h rom.h device.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_icd2061.d b/src/vid_icd2061.d new file mode 100644 index 000000000..5c6ce7cd6 --- /dev/null +++ b/src/vid_icd2061.d @@ -0,0 +1 @@ +vid_icd2061.o: video/vid_icd2061.c 86box.h device.h diff --git a/src/vid_ics2595.d b/src/vid_ics2595.d new file mode 100644 index 000000000..06f34d1cf --- /dev/null +++ b/src/vid_ics2595.d @@ -0,0 +1 @@ +vid_ics2595.o: video/vid_ics2595.c 86box.h device.h diff --git a/src/vid_im1024.d b/src/vid_im1024.d new file mode 100644 index 000000000..4d6c4332a --- /dev/null +++ b/src/vid_im1024.d @@ -0,0 +1,3 @@ +vid_im1024.o: video/vid_im1024.c 86box.h 86box_io.h mem.h rom.h timer.h \ + cpu_common/cpu.h device.h pit.h plat.h lang/language.h video/video.h \ + video/vid_pgc.h diff --git a/src/vid_incolor.d b/src/vid_incolor.d new file mode 100644 index 000000000..90d2e6d90 --- /dev/null +++ b/src/vid_incolor.d @@ -0,0 +1,2 @@ +vid_incolor.o: video/vid_incolor.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h lpt.h pit.h mem.h rom.h device.h video/video.h diff --git a/src/vid_mda.d b/src/vid_mda.d new file mode 100644 index 000000000..38fdba556 --- /dev/null +++ b/src/vid_mda.d @@ -0,0 +1,2 @@ +vid_mda.o: video/vid_mda.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + lpt.h pit.h mem.h rom.h device.h video/video.h video/vid_mda.h diff --git a/src/vid_mga.d b/src/vid_mga.d new file mode 100644 index 000000000..4cb1b39d6 --- /dev/null +++ b/src/vid_mga.d @@ -0,0 +1,3 @@ +vid_mga.o: video/vid_mga.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + mem.h pci.h rom.h device.h plat.h lang/language.h video/video.h \ + video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_oak_oti.d b/src/vid_oak_oti.d new file mode 100644 index 000000000..113233ed3 --- /dev/null +++ b/src/vid_oak_oti.d @@ -0,0 +1,2 @@ +vid_oak_oti.o: video/vid_oak_oti.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mem.h rom.h device.h video/video.h video/vid_svga.h diff --git a/src/vid_paradise.d b/src/vid_paradise.d new file mode 100644 index 000000000..2bfeb515a --- /dev/null +++ b/src/vid_paradise.d @@ -0,0 +1,3 @@ +vid_paradise.o: video/vid_paradise.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mem.h rom.h device.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_pgc.d b/src/vid_pgc.d new file mode 100644 index 000000000..c52e58999 --- /dev/null +++ b/src/vid_pgc.d @@ -0,0 +1,3 @@ +vid_pgc.o: video/vid_pgc.c 86box.h 86box_io.h mem.h rom.h timer.h \ + cpu_common/cpu.h device.h pit.h plat.h lang/language.h video/video.h \ + video/vid_cga.h video/vid_pgc.h video/vid_pgc_palette.h diff --git a/src/vid_s3.d b/src/vid_s3.d new file mode 100644 index 000000000..a0ef7daa8 --- /dev/null +++ b/src/vid_s3.d @@ -0,0 +1,3 @@ +vid_s3.o: video/vid_s3.c 86box.h device.h 86box_io.h timer.h \ + cpu_common/cpu.h mem.h pci.h rom.h plat.h lang/language.h video/video.h \ + video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_s3_virge.d b/src/vid_s3_virge.d new file mode 100644 index 000000000..a0ccbe92e --- /dev/null +++ b/src/vid_s3_virge.d @@ -0,0 +1,3 @@ +vid_s3_virge.o: video/vid_s3_virge.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mem.h pci.h rom.h device.h plat.h lang/language.h \ + video/video.h video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_sc1502x_ramdac.d b/src/vid_sc1502x_ramdac.d new file mode 100644 index 000000000..d55bd16cb --- /dev/null +++ b/src/vid_sc1502x_ramdac.d @@ -0,0 +1,3 @@ +vid_sc1502x_ramdac.o: video/vid_sc1502x_ramdac.c video/../86box.h \ + video/../device.h video/../mem.h video/../timer.h cpu_common/cpu.h \ + video/video.h video/vid_svga.h diff --git a/src/vid_sdac_ramdac.d b/src/vid_sdac_ramdac.d new file mode 100644 index 000000000..a86391818 --- /dev/null +++ b/src/vid_sdac_ramdac.d @@ -0,0 +1,2 @@ +vid_sdac_ramdac.o: video/vid_sdac_ramdac.c 86box.h device.h mem.h timer.h \ + cpu_common/cpu.h video/video.h video/vid_svga.h diff --git a/src/vid_sigma.d b/src/vid_sigma.d new file mode 100644 index 000000000..d7cb59ca8 --- /dev/null +++ b/src/vid_sigma.d @@ -0,0 +1,2 @@ +vid_sigma.o: video/vid_sigma.c 86box.h cpu_common/cpu.h 86box_io.h \ + timer.h pit.h mem.h nmi.h rom.h device.h video/video.h diff --git a/src/vid_stg_ramdac.d b/src/vid_stg_ramdac.d new file mode 100644 index 000000000..f5acb127b --- /dev/null +++ b/src/vid_stg_ramdac.d @@ -0,0 +1,3 @@ +vid_stg_ramdac.o: video/vid_stg_ramdac.c video/../86box.h \ + video/../device.h video/../mem.h video/../timer.h cpu_common/cpu.h \ + video/video.h video/vid_svga.h diff --git a/src/vid_svga.d b/src/vid_svga.d new file mode 100644 index 000000000..a48fa3b9f --- /dev/null +++ b/src/vid_svga.d @@ -0,0 +1,3 @@ +vid_svga.o: video/vid_svga.c 86box.h cpu_common/cpu.h machine/machine.h \ + timer.h 86box_io.h pit.h mem.h rom.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_svga_render.d b/src/vid_svga_render.d new file mode 100644 index 000000000..1e172d2ec --- /dev/null +++ b/src/vid_svga_render.d @@ -0,0 +1,2 @@ +vid_svga_render.o: video/vid_svga_render.c 86box.h mem.h timer.h \ + cpu_common/cpu.h video/video.h video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_table.d b/src/vid_table.d new file mode 100644 index 000000000..ad56e481a --- /dev/null +++ b/src/vid_table.d @@ -0,0 +1,4 @@ +vid_table.o: video/vid_table.c 86box.h timer.h cpu_common/cpu.h \ + machine/machine.h mem.h device.h plat.h lang/language.h video/video.h \ + video/vid_svga.h video/vid_cga.h video/vid_ega.h video/vid_colorplus.h \ + video/vid_mda.h diff --git a/src/vid_tgui9440.d b/src/vid_tgui9440.d new file mode 100644 index 000000000..8198c0476 --- /dev/null +++ b/src/vid_tgui9440.d @@ -0,0 +1,3 @@ +vid_tgui9440.o: video/vid_tgui9440.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mem.h pci.h rom.h device.h plat.h lang/language.h \ + video/video.h video/vid_svga.h video/vid_svga_render.h diff --git a/src/vid_ti_cf62011.d b/src/vid_ti_cf62011.d new file mode 100644 index 000000000..9dcc37af6 --- /dev/null +++ b/src/vid_ti_cf62011.d @@ -0,0 +1,2 @@ +vid_ti_cf62011.o: video/vid_ti_cf62011.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h mem.h rom.h device.h video/video.h video/vid_svga.h diff --git a/src/vid_tkd8001_ramdac.d b/src/vid_tkd8001_ramdac.d new file mode 100644 index 000000000..c4505bc81 --- /dev/null +++ b/src/vid_tkd8001_ramdac.d @@ -0,0 +1,2 @@ +vid_tkd8001_ramdac.o: video/vid_tkd8001_ramdac.c 86box.h device.h timer.h \ + cpu_common/cpu.h mem.h video/video.h video/vid_svga.h diff --git a/src/vid_tvga.d b/src/vid_tvga.d new file mode 100644 index 000000000..27a372f26 --- /dev/null +++ b/src/vid_tvga.d @@ -0,0 +1,3 @@ +vid_tvga.o: video/vid_tvga.c 86box.h 86box_io.h timer.h cpu_common/cpu.h \ + mem.h rom.h device.h video/video.h video/vid_svga.h \ + video/vid_svga_render.h diff --git a/src/vid_vga.d b/src/vid_vga.d new file mode 100644 index 000000000..6b4c2180f --- /dev/null +++ b/src/vid_vga.d @@ -0,0 +1,2 @@ +vid_vga.o: video/vid_vga.c 86box.h 86box_io.h mem.h rom.h device.h \ + timer.h cpu_common/cpu.h video/video.h video/vid_svga.h diff --git a/src/vid_voodoo.d b/src/vid_voodoo.d new file mode 100644 index 000000000..dc763ab20 --- /dev/null +++ b/src/vid_voodoo.d @@ -0,0 +1,4 @@ +vid_voodoo.o: video/vid_voodoo.c 86box.h cpu_common/cpu.h \ + machine/machine.h device.h mem.h pci.h rom.h timer.h plat.h \ + lang/language.h video/video.h video/vid_svga.h video/vid_voodoo_dither.h \ + video/vid_voodoo_codegen_x86.h diff --git a/src/vid_wy700.d b/src/vid_wy700.d new file mode 100644 index 000000000..c27e81bea --- /dev/null +++ b/src/vid_wy700.d @@ -0,0 +1,2 @@ +vid_wy700.o: video/vid_wy700.c 86box.h 86box_io.h timer.h \ + cpu_common/cpu.h pit.h mem.h device.h video/video.h diff --git a/src/video.d b/src/video.d new file mode 100644 index 000000000..d63ce7bb4 --- /dev/null +++ b/src/video.d @@ -0,0 +1,5 @@ +video.o: video/video.c C:/msys64_gcc91/mingw32/include/libpng16/png.h \ + C:/msys64_gcc91/mingw32/include/libpng16/pnglibconf.h \ + C:/msys64_gcc91/mingw32/include/libpng16/pngconf.h 86box.h \ + cpu_common/cpu.h 86box_io.h mem.h rom.h config.h timer.h plat.h \ + lang/language.h video/video.h video/vid_svga.h diff --git a/src/video/86Box.exe b/src/video/86Box.exe new file mode 100644 index 000000000..56b0faadc Binary files /dev/null and b/src/video/86Box.exe differ diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index a62129f7d..2a4f9380d 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -21,14 +21,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" -#include "vid_ati18800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_ati18800.h b/src/video/vid_ati18800.h deleted file mode 100644 index b41facab3..000000000 --- a/src/video/vid_ati18800.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t ati18800_wonder_device; -extern const device_t ati18800_vga88_device; -extern const device_t ati18800_device; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 28081efe9..29dd9cc4f 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -25,18 +25,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" -#include "vid_ati28800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_sc1502x_ramdac.h" #define VGAWONDERXL 1 diff --git a/src/video/vid_ati28800.h b/src/video/vid_ati28800.h deleted file mode 100644 index 9db0fa7bc..000000000 --- a/src/video/vid_ati28800.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t ati28800_device; -extern const device_t ati28800k_device; -extern const device_t compaq_ati28800_device; -#if defined(DEV_BRANCH) && defined(USE_XL24) -extern const device_t ati28800_wonderxl24_device; -#endif diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index c814352b2..e0af06b45 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -41,19 +41,34 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_ati68860_ramdac.h" #include "vid_svga_render.h" -void -ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) +typedef struct ati68860_ramdac_t { + uint8_t regs[16]; + void (*render)(struct svga_t *svga); + + int dac_addr, dac_pos; + int dac_r, dac_g; + PALETTE pal; + uint32_t pallook[2]; + + int ramdac_type; +} ati68860_ramdac_t; + + +void +ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + switch (addr) { case 0: svga_out(0x3c8, val, svga); @@ -143,8 +158,9 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_ } uint8_t -ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) +ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) { + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; uint8_t temp = 0; switch (addr) { @@ -180,8 +196,9 @@ ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) void -ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type) +ati68860_set_ramdac_type(void *p, int type) { + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; int c; if (ramdac->ramdac_type != type) { @@ -211,6 +228,55 @@ ati68860_ramdac_init(const device_t *info) } +void +ati68860_ramdac_set_render(void *p, svga_t *svga) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + + svga->render = ramdac->render; +} + + +void +ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; + + ramdac->pallook[i] = col; +} + + +void +ati68860_hwcursor_draw(svga_t *svga, int displine) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + int x, offset; + uint8_t dat; + uint32_t col0 = ramdac->pallook[0]; + uint32_t col1 = ramdac->pallook[1]; + + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; + dat >>= 2; + offset += 4; + } + + svga->hwcursor_latch.addr += 16; +} + + static void ati68860_ramdac_close(void *priv) { diff --git a/src/video/vid_ati68860_ramdac.h b/src/video/vid_ati68860_ramdac.h deleted file mode 100644 index 33e59ebc3..000000000 --- a/src/video/vid_ati68860_ramdac.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * ATI 68860 RAMDAC emulation header (for Mach64) - * - * Version: @(#)vid_ati68860.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct ati68860_ramdac_t -{ - uint8_t regs[16]; - void (*render)(struct svga_t *svga); - - int dac_addr, dac_pos; - int dac_r, dac_g; - PALETTE pal; - uint32_t pallook[2]; - - int ramdac_type; -} ati68860_ramdac_t; - -extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga); -extern uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga); -extern void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type); - -extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index a7fee5958..ea499788d 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -20,11 +20,11 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" -#include "../nvr.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" +#include "nvr.h" #include "vid_ati_eeprom.h" diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index a27621dde..576b2c774 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -23,20 +23,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../pci.h" -#include "../rom.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "pci.h" +#include "rom.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_ati68860_ramdac.h" #include "vid_ati_eeprom.h" -#include "vid_ics2595.h" #ifdef CLAMP #undef CLAMP @@ -460,8 +458,6 @@ uint8_t mach64_in(uint16_t addr, void *p) void mach64_recalctimings(svga_t *svga) { mach64_t *mach64 = (mach64_t *)svga->p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - ics2595_t *clock_gen = (ics2595_t *) svga->clock_gen; if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { @@ -471,7 +467,7 @@ void mach64_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); - svga->clock = (cpuclock * (double)(1ull << 32)) / clock_gen->output_clock; + svga->clock = (cpuclock * (double)(1ull << 32)) / ics2595_getclock(svga->clock_gen); svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; @@ -479,7 +475,7 @@ void mach64_recalctimings(svga_t *svga) svga->rowcount = mach64->crtc_gen_cntl & 1; svga->rowoffset <<= 1; if (mach64->type == MACH64_GX) - svga->render = ramdac->render; + ati68860_ramdac_set_render(svga->ramdac, svga); switch ((mach64->crtc_gen_cntl >> 8) & 7) { case 1: @@ -1717,7 +1713,6 @@ static void mach64_vblank_start(svga_t *svga) uint8_t mach64_ext_readb(uint32_t addr, void *p) { mach64_t *mach64 = (mach64_t *)p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; uint8_t ret; if (!(addr & 0x400)) @@ -1843,9 +1838,9 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) case 0xc0: case 0xc1: case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), ramdac, &mach64->svga); + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(addr & 3, ramdac, &mach64->svga); + ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: if (mach64->type == MACH64_VT2) @@ -2142,8 +2137,6 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; svga_t *svga = &mach64->svga; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - ics2595_t *clock_gen = (ics2595_t *) svga->clock_gen; mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val); @@ -2260,12 +2253,12 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x60: case 0x61: case 0x62: case 0x63: WRITE8(addr, mach64->cur_clr0, val); if (mach64->type == MACH64_VT2) - ramdac->pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); + ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff)); break; case 0x64: case 0x65: case 0x66: case 0x67: WRITE8(addr, mach64->cur_clr1, val); if (mach64->type == MACH64_VT2) - ramdac->pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); + ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff)); break; case 0x68: case 0x69: case 0x6a: case 0x6b: WRITE8(addr, mach64->cur_offset, val); @@ -2295,11 +2288,11 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x90: case 0x91: case 0x92: case 0x93: WRITE8(addr, mach64->clock_cntl, val); if (mach64->type == MACH64_GX) - ics2595_write(clock_gen, val & 0x40, val & 0xf); + ics2595_write(svga->clock_gen, val & 0x40, val & 0xf); else { pll_write(mach64, addr, val); - clock_gen->output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; + ics2595_setclock(svga->clock_gen, mach64->pll_freq[mach64->clock_cntl & 3]); } svga_recalctimings(&mach64->svga); break; @@ -2327,14 +2320,14 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0xc0: case 0xc1: case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, ramdac, &mach64->svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); else - ati68860_ramdac_out(addr & 3, val, ramdac, &mach64->svga); + ati68860_ramdac_out(addr & 3, val, mach64->svga.ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: WRITE8(addr, mach64->dac_cntl, val); svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - ati68860_set_ramdac_type(ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + ati68860_set_ramdac_type(mach64->svga.ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: @@ -2407,7 +2400,6 @@ void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) uint8_t mach64_ext_inb(uint16_t port, void *p) { mach64_t *mach64 = (mach64_t *)p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; uint8_t ret; switch (port) @@ -2494,9 +2486,9 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), ramdac, &mach64->svga); + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(port & 3, ramdac, &mach64->svga); + ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: @@ -2564,7 +2556,6 @@ uint32_t mach64_ext_inl(uint16_t port, void *p) void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); switch (port) @@ -2647,9 +2638,9 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, ramdac, &mach64->svga); + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); else - ati68860_ramdac_out(port & 3, val, ramdac, &mach64->svga); + ati68860_ramdac_out(port & 3, val, mach64->svga.ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: @@ -2789,34 +2780,6 @@ uint32_t mach64_readl(uint32_t addr, void *p) return svga_readl_linear(addr, svga); } -void mach64_hwcursor_draw(svga_t *svga, int displine) -{ - ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - int x, offset; - uint8_t dat; - uint32_t col0 = ramdac->pallook[0]; - uint32_t col1 = ramdac->pallook[1]; - - offset = svga->hwcursor_latch.xoff; - for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) - { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; -} #define CLAMP(x) do \ { \ @@ -3306,7 +3269,7 @@ static void *mach64_common_init(const device_t *info) svga_init(&mach64->svga, mach64, mach64->vram_size << 20, mach64_recalctimings, mach64_in, mach64_out, - mach64_hwcursor_draw, + NULL, mach64_overlay_draw); if (info->flags & DEVICE_PCI) @@ -3331,6 +3294,8 @@ static void *mach64_common_init(const device_t *info) mach64->pci_regs[0x33] = 0x00; mach64->svga.ramdac = device_add(&ati68860_ramdac_device); + mach64->svga.dac_hwcursor_draw = ati68860_hwcursor_draw; + mach64->svga.clock_gen = device_add(&ics2595_device); mach64->dst_cntl = 3; diff --git a/src/video/vid_ati_mach64.h b/src/video/vid_ati_mach64.h deleted file mode 100644 index c44444d7a..000000000 --- a/src/video/vid_ati_mach64.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * ATi Mach64 graphics card emulation. - * - * Version: @(#)vid_ati_mach64.h 1.0.2 2018/03/18 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -extern const device_t mach64gx_isa_device; -extern const device_t mach64gx_vlb_device; -extern const device_t mach64gx_pci_device; -extern const device_t mach64vt2_device; diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index 1077c7e54..bce0a21c9 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -21,13 +21,21 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_att20c49x_ramdac.h" + + +typedef struct +{ + int type; + int state; + uint8_t ctrl; +} att49x_ramdac_t; + enum { @@ -35,9 +43,12 @@ enum ATT_492_3 }; + void -att49x_ramdac_out(uint16_t addr, uint8_t val, att49x_ramdac_t *ramdac, svga_t *svga) +att49x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + switch (addr) { case 0x3C6: if (ramdac->state == 4) { @@ -93,10 +104,10 @@ att49x_ramdac_out(uint16_t addr, uint8_t val, att49x_ramdac_t *ramdac, svga_t *s uint8_t -att49x_ramdac_in(uint16_t addr, att49x_ramdac_t *ramdac, svga_t *svga) +att49x_ramdac_in(uint16_t addr, void *p, svga_t *svga) { - uint8_t temp; - temp = svga_in(addr, svga); + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + uint8_t temp = svga_in(addr, svga); switch (addr) { case 0x3C6: diff --git a/src/video/vid_att20c49x_ramdac.h b/src/video/vid_att20c49x_ramdac.h deleted file mode 100644 index 2a191afcf..000000000 --- a/src/video/vid_att20c49x_ramdac.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header of the emulation of a Sierra SC1502X RAMDAC. - * - * Used by the TLIVESA1 driver for ET4000. - * - * Version: @(#)vid_sc1502x_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct -{ - int type; - int state; - uint8_t ctrl; -} att49x_ramdac_t; - -extern void att49x_ramdac_out(uint16_t addr, uint8_t val, att49x_ramdac_t *ramdac, svga_t *svga); -extern uint8_t att49x_ramdac_in(uint16_t addr, att49x_ramdac_t *ramdac, svga_t *svga); - -extern const device_t att490_ramdac_device; -extern const device_t att492_ramdac_device; diff --git a/src/video/vid_av9194.c b/src/video/vid_av9194.c index ad3f706a1..bc48c08b7 100644 --- a/src/video/vid_av9194.c +++ b/src/video/vid_av9194.c @@ -21,9 +21,12 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "vid_av9194.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" +#include "video.h" +#include "vid_svga.h" float diff --git a/src/video/vid_av9194.h b/src/video/vid_av9194.h deleted file mode 100644 index 11760fe53..000000000 --- a/src/video/vid_av9194.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * AV9194 clock generator emulation. - * - * Used by the S3 86c801 (V7-Mirage) card. - * - * Version: @(#)vid_av9194.c 1.0.1 2019/01/12 - * - * Authors: Miran Grca, - * - * Copyright 2016-2018 Miran Grca. - */ -float av9194_getclock(int clock, void *p); - -extern const device_t av9194_device; diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index 53dec87a6..20baf13eb 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -22,13 +22,29 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_bt48x_ramdac.h" + + +typedef struct +{ + PALETTE extpal; + uint32_t extpallook[256]; + uint8_t cursor32_data[256]; + uint8_t cursor64_data[1024]; + int hwc_y, hwc_x; + uint8_t cmd_r0; + uint8_t cmd_r1; + uint8_t cmd_r2; + uint8_t cmd_r3; + uint8_t cmd_r4; + uint8_t status; + uint8_t type; +} bt48x_ramdac_t; enum { @@ -69,8 +85,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) void -bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *ramdac, svga_t *svga) +bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) { + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; uint32_t o32; uint8_t *cd; uint16_t index; @@ -209,8 +226,9 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *r uint8_t -bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t *svga) +bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) { + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; uint8_t temp = 0xff; uint8_t *cd; uint16_t index; @@ -330,6 +348,17 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t } +void +bt48x_recalctimings(void *p, svga_t *svga) +{ + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; + + svga->interlace = ramdac->cmd_r2 & 0x08; + if (ramdac->cmd_r3 & 0x08) + svga->hdisp *= 2; /* x2 clock multiplier */ +} + + void bt48x_hwcursor_draw(svga_t *svga, int displine) { diff --git a/src/video/vid_bt48x_ramdac.h b/src/video/vid_bt48x_ramdac.h deleted file mode 100644 index ce952e1e8..000000000 --- a/src/video/vid_bt48x_ramdac.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header of the emulation of the Brooktree BT484-BT485A - * true colour RAMDAC family. - * - * Version: @(#)vid_bt485_ramdac.h 1.0.5 2019/01/12 - * - * Authors: Miran Grca, - * TheCollector1995, - * - * Copyright 2016-2018 Miran Grca. - * Copyright 2018 TheCollector1995. - */ -typedef struct -{ - PALETTE extpal; - uint32_t extpallook[256]; - uint8_t cursor32_data[256]; - uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; - uint8_t cmd_r0; - uint8_t cmd_r1; - uint8_t cmd_r2; - uint8_t cmd_r3; - uint8_t cmd_r4; - uint8_t status; - uint8_t type; -} bt48x_ramdac_t; - -extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *ramdac, svga_t *svga); -extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t *svga); -extern void bt48x_hwcursor_draw(svga_t *svga, int displine); - -extern const device_t bt484_ramdac_device; -extern const device_t att20c504_ramdac_device; -extern const device_t bt485_ramdac_device; -extern const device_t att20c505_ramdac_device; -extern const device_t bt485a_ramdac_device; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 2cb05a1d2..91f04501b 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -22,14 +22,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_cga.h" #include "vid_cga_comp.h" diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index b5e87078f..0d4d5a0a5 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -23,9 +23,9 @@ #include #include #include -#include "../86box.h" -#include "../timer.h" -#include "../mem.h" +#include "86box.h" +#include "timer.h" +#include "mem.h" #include "vid_cga.h" #include "vid_cga_comp.h" diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 65e2d66f0..8749fa0d9 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.32 2020/01/22 + * Version: @(#)vid_cl_54xx.c 1.0.33 2020/01/22 * * Authors: TheCollector1995, * Miran Grca, @@ -23,20 +23,20 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_cl54xx.h" #define BIOS_GD5402_PATH L"roms/video/cirruslogic/avga2.rom" +#define BIOS_GD5402_ONBOARD_PATH L"roms/video/machines/cbm_sl386sx25/Commodore386SX-25_AVGA2.bin" #define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi" #if defined(DEV_BRANCH) && defined(USE_CL5422) @@ -2910,7 +2910,10 @@ static void switch (id) { case CIRRUS_ID_CLGD5402: - romfn = BIOS_GD5402_PATH; + if (info->local & 0x200) + romfn = BIOS_GD5402_ONBOARD_PATH; + else + romfn = BIOS_GD5402_PATH; break; case CIRRUS_ID_CLGD5420: @@ -3307,7 +3310,7 @@ const device_t gd5402_onboard_device = { "Cirrus Logic GD-5402 (ACUMOS AVGA2) (On-Board)", DEVICE_AT | DEVICE_ISA, - CIRRUS_ID_CLGD5402, + CIRRUS_ID_CLGD5402 | 0x200, gd54xx_init, gd54xx_close, NULL, NULL, diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h deleted file mode 100644 index 10c3eea0f..000000000 --- a/src/video/vid_cl54xx.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t gd5402_isa_device; -extern const device_t gd5402_onboard_device; -extern const device_t gd5420_isa_device; -#if defined(DEV_BRANCH) && defined(USE_CL5422) -extern const device_t gd5422_isa_device; -extern const device_t gd5424_vlb_device; -#endif -extern const device_t gd5426_vlb_device; -extern const device_t gd5428_isa_device; -extern const device_t gd5428_vlb_device; -extern const device_t gd5429_isa_device; -extern const device_t gd5429_vlb_device; -extern const device_t gd5430_vlb_device; -extern const device_t gd5430_pci_device; -extern const device_t gd5434_isa_device; -extern const device_t gd5434_vlb_device; -extern const device_t gd5434_pci_device; -extern const device_t gd5436_pci_device; -extern const device_t gd5440_onboard_pci_device; -extern const device_t gd5440_pci_device; -extern const device_t gd5446_pci_device; -extern const device_t gd5446_stb_pci_device; -extern const device_t gd5480_pci_device; \ No newline at end of file diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 80393ecbb..93fad1cc8 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -22,14 +22,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "mem.h" +#include "device.h" #include "video.h" #include "vid_cga.h" #include "vid_colorplus.h" diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index f17c526a1..d6bf29a72 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -24,14 +24,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_cga.h" #include "vid_cga_comp.h" diff --git a/src/video/vid_compaq_cga.h b/src/video/vid_compaq_cga.h deleted file mode 100644 index e6c684d52..000000000 --- a/src/video/vid_compaq_cga.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef VIDEO_COMPAQ_CGA_H -# define VIDEO_COMPAQ_CGA_H - - -#ifdef EMU_DEVICE_H -extern const device_t compaq_cga_device; -extern const device_t compaq_cga_2_device; -#endif - - -#endif /*VIDEO_COMPAQ_CGA_H*/ diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 05c617e2c..0b8753bd1 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -22,18 +22,17 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_ati_eeprom.h" #include "vid_ega.h" -#include "vid_ega_render.h" void ega_doblit(int y1, int y2, int wx, int wy, ega_t *ega); diff --git a/src/video/vid_ega.h b/src/video/vid_ega.h index 099fab4a0..170a91090 100644 --- a/src/video/vid_ega.h +++ b/src/video/vid_ega.h @@ -100,4 +100,32 @@ extern void ega_write(uint32_t addr, uint8_t val, void *p); extern uint8_t ega_read(uint32_t addr, void *p); +extern int firstline_draw, lastline_draw; +extern int displine; +extern int sc; + +extern uint32_t ma, ca; +extern int con, cursoron, cgablink; + +extern int scrollcache; + +extern uint8_t edatlookup[4][4]; + +#if defined(EMU_MEM_H) && defined(EMU_ROM_H) +void ega_render_blank(ega_t *ega); + +void ega_render_overscan_left(ega_t *ega); +void ega_render_overscan_right(ega_t *ega); + +void ega_render_text_40(ega_t *ega); +void ega_render_text_80(ega_t *ega); + +void ega_render_2bpp_lowres(ega_t *ega); +void ega_render_2bpp_highres(ega_t *ega); + +void ega_render_4bpp_lowres(ega_t *ega); +void ega_render_4bpp_highres(ega_t *ega); +#endif + + #endif /*VIDEO_EGA_H*/ diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index cf5ec7d50..471d3c531 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -20,14 +20,13 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" #include "video.h" #include "vid_ega.h" -#include "vid_ega_render.h" int diff --git a/src/video/vid_ega_render.h b/src/video/vid_ega_render.h deleted file mode 100644 index a905fc5dd..000000000 --- a/src/video/vid_ega_render.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * EGA renderers. - * - * Version: @(#)vid_ega_render.h 1.0.3 2019/10/03 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - */ - -extern int firstline_draw, lastline_draw; -extern int displine; -extern int sc; - -extern uint32_t ma, ca; -extern int con, cursoron, cgablink; - -extern int scrollcache; - -extern uint8_t edatlookup[4][4]; - -void ega_render_blank(ega_t *ega); - -void ega_render_overscan_left(ega_t *ega); -void ega_render_overscan_right(ega_t *ega); - -void ega_render_text_40(ega_t *ega); -void ega_render_text_80(ega_t *ega); - -void ega_render_2bpp_lowres(ega_t *ega); -void ega_render_2bpp_highres(ega_t *ega); - -void ega_render_4bpp_lowres(ega_t *ega); -void ega_render_4bpp_highres(ega_t *ega); diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 3702098df..ad4bd13a9 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -8,7 +8,7 @@ * * Emulation of the Tseng Labs ET4000. * - * Version: @(#)vid_et4000.c 1.0.20 2018/10/04 + * Version: @(#)vid_et4000.c 1.0.20 2018/10/04e * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,18 +42,16 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mca.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_sc1502x_ramdac.h" -#include "vid_et4000.h" #define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin" diff --git a/src/video/vid_et4000.h b/src/video/vid_et4000.h deleted file mode 100644 index b0a566c61..000000000 --- a/src/video/vid_et4000.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the Tseng Labs ET4000. - * - * Version: @(#)vid_et4000.c 1.0.9 2018/08/16 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#ifndef EMU_VID_ET4000_H -# define EMU_VID_ET4000_H - -extern const device_t et4000_isa_device; -extern const device_t et4000k_isa_device; -extern const device_t et4000k_tg286_isa_device; -extern const device_t et4000_mca_device; - -#endif /*EMU_VID_ET4000_H*/ \ No newline at end of file diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c941d85fd..ccd8a6aee 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -25,19 +25,17 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "timer.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_icd2061.h" -#include "vid_stg_ramdac.h" #define BIOS_ROM_PATH_DIAMOND L"roms/video/et4000w32/et4000w32.bin" diff --git a/src/video/vid_et4000w32.h b/src/video/vid_et4000w32.h deleted file mode 100644 index 350933be5..000000000 --- a/src/video/vid_et4000w32.h +++ /dev/null @@ -1,5 +0,0 @@ -extern const device_t et4000w32p_vlb_device; -extern const device_t et4000w32p_pci_device; - -extern const device_t et4000w32p_cardex_vlb_device; -extern const device_t et4000w32p_cardex_pci_device; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 89f40da8c..9f76ada3e 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -21,17 +21,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "plat.h" #include "video.h" -#include "vid_genius.h" #define BIOS_ROM_PATH L"roms/video/genius/8x12.bin" diff --git a/src/video/vid_genius.h b/src/video/vid_genius.h deleted file mode 100644 index e1388ec5c..000000000 --- a/src/video/vid_genius.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t genius_device; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index fd3c85284..15538431f 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -21,17 +21,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "mem.h" +#include "rom.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "device.h" #include "video.h" -#include "vid_hercules.h" typedef struct { diff --git a/src/video/vid_hercules.h b/src/video/vid_hercules.h deleted file mode 100644 index 3c145e18f..000000000 --- a/src/video/vid_hercules.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t hercules_device; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 2a4497bce..fc4f0ad97 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -21,16 +21,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../lpt.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "lpt.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_herculesplus.h" /* extended CRTC registers */ diff --git a/src/video/vid_herculesplus.h b/src/video/vid_herculesplus.h deleted file mode 100644 index 72b47c35f..000000000 --- a/src/video/vid_herculesplus.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: John Elliott - see COPYING for more details -*/ -extern const device_t herculesplus_device; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index a0479a696..bb7be328c 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -21,18 +21,17 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../pic.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "timer.h" +#include "pic.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_ht216.h" typedef struct ht216_t diff --git a/src/video/vid_ht216.h b/src/video/vid_ht216.h deleted file mode 100644 index abb15bba9..000000000 --- a/src/video/vid_ht216.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Video 7 VGA 1024i emulation header. - * - * Version: @(#)vid_ht216.h 1.0.1 2019/10/01 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2019 Sarah Walker. - * Copyright 2019 Miran Grca. - */ -extern const device_t g2_gc205_device; -extern const device_t v7_vga_1024i_device; -extern const device_t ht216_32_pb410a_device; diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 1c1746df5..7dbe9d3ca 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -25,9 +25,18 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "vid_icd2061.h" +#include "86box.h" +#include "device.h" + + +typedef struct icd2061_t +{ + float freq[3]; + + int count, bit_count, + unlocked, state; + uint32_t data, ctrl; +} icd2061_t; #ifdef ENABLE_ICD2061_LOG @@ -51,10 +60,12 @@ icd2061_log(const char *fmt, ...) void -icd2061_write(icd2061_t *icd2061, int val) +icd2061_write(void *p, int val) { + icd2061_t *icd2061 = (icd2061_t *) p; + int nd, oc, nc; - int a, qa, q, pa, p, m, ps; + int a, qa, q, pa, p_, m, ps; nd = (val & 2) >> 1; /* Old data. */ oc = icd2061->state & 1; /* Old clock. */ @@ -96,14 +107,14 @@ icd2061_write(icd2061_t *icd2061, int val) m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */ qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */ - p = pa + 3; /* P (ICD2061) / N (ICS9161) */ + p_ = pa + 3; /* P (ICD2061) / N (ICS9161) */ m = 1 << m; q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float)(p * ps) / (float)(q * m)) * 14318184.0f; + icd2061->freq[a] = ((float)(p_ * ps) / (float)(q * m)) * 14318184.0f; - icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p, m, q, a, icd2061->freq[a]); + icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); } else if (a == 6) { icd2061->ctrl = ((icd2061->data >> 13) & 0xff); icd2061_log("ctrl = %02X\n", icd2061->ctrl); diff --git a/src/video/vid_icd2061.h b/src/video/vid_icd2061.h deleted file mode 100644 index 5b1c853e3..000000000 --- a/src/video/vid_icd2061.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * ICD2061 clock generator emulation header. - * Also emulates the ICS9161 which is the same as the ICD2016, - * but without the need for tuning (which is irrelevant in - * emulation anyway). - * - * Used by ET4000w32/p (Diamond Stealth 32) and the S3 - * Vision964 family. - * - * Version: @(#)vid_icd2061.h 1.0.3 2018/10/04 - * - * Authors: Miran Grca, - * - * Copyright 2018 Miran Grca. - */ -typedef struct icd2061_t -{ - float freq[3]; - - int count, bit_count; - int unlocked, state; - uint32_t data, ctrl; -} icd2061_t; - -void icd2061_write(icd2061_t *icd2061, int val); -float icd2061_getclock(int clock, void *p); - -extern const device_t icd2061_device; -extern const device_t ics9161_device; - -/* The code is the same, the #define's are so that the correct name can be used. */ -#define ics9161_write icd2061_write -#define ics9161_getclock icd2061_getclock diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index 711fb4641..374dda318 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -21,9 +21,19 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "vid_ics2595.h" +#include "86box.h" +#include "device.h" + + +typedef struct ics2595_t +{ + int oldfs3, oldfs2; + int dat; + int pos, state; + + double clocks[16]; + double output_clock; +} ics2595_t; enum @@ -38,9 +48,11 @@ static int ics2595_div[4] = {8, 4, 2, 1}; void -ics2595_write(ics2595_t *ics2595, int strobe, int dat) +ics2595_write(void *p, int strobe, int dat) { - int d, n, l; + ics2595_t *ics2595 = (ics2595_t *) p; + int d, n; + int l; if (strobe) { if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/ @@ -94,6 +106,24 @@ ics2595_close(void *priv) } +double +ics2595_getclock(void *p) +{ + ics2595_t *ics2595 = (ics2595_t *) p; + + return ics2595->output_clock; +} + + +void +ics2595_setclock(void *p, double clock) +{ + ics2595_t *ics2595 = (ics2595_t *) p; + + ics2595->output_clock = clock; +} + + const device_t ics2595_device = { "ICS2595 clock chip", diff --git a/src/video/vid_ics2595.h b/src/video/vid_ics2595.h deleted file mode 100644 index 1453a38ba..000000000 --- a/src/video/vid_ics2595.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * ICS2595 clock chip emulation header. Used by ATI Mach64. - * - * Version: @(#)vid_ics2595.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct ics2595_t -{ - int oldfs3, oldfs2; - int dat; - int pos, state; - - double clocks[16]; - double output_clock; -} ics2595_t; - -extern void ics2595_write(ics2595_t *ics2595, int strobe, int dat); - -extern const device_t ics2595_device; diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index 00954e2d6..301c0fd6e 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -54,17 +54,16 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../pit.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "pit.h" +#include "plat.h" #include "video.h" #include "vid_pgc.h" -#include "vid_im1024.h" #define BIOS_ROM_PATH L"roms/video/im1024/im1024font.bin" diff --git a/src/video/vid_im1024.h b/src/video/vid_im1024.h deleted file mode 100644 index bf716b1d3..000000000 --- a/src/video/vid_im1024.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header of the emulation of the ImageManager 1024 video - * controller. - * - * Version: @(#)vid_im1024.h 1.0.0 2019/03/03 - * - * Authors: John Elliott, - * - * Copyright 2019 John Elliott. - */ -extern const device_t im1024_device; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index bd0d6e36f..d2373a836 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -21,16 +21,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_incolor.h" /* extended CRTC registers */ diff --git a/src/video/vid_incolor.h b/src/video/vid_incolor.h deleted file mode 100644 index d75a97186..000000000 --- a/src/video/vid_incolor.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: John Elliott - see COPYING for more details -*/ -extern const device_t incolor_device; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 2651e30ea..5e8abac8d 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -21,14 +21,14 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../lpt.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "lpt.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_mda.h" diff --git a/src/video/vid_mga - Cópia.c b/src/video/vid_mga - Cópia.c new file mode 100644 index 000000000..4c26b8676 --- /dev/null +++ b/src/video/vid_mga - Cópia.c @@ -0,0 +1,4876 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Matrox MGA graphics card emulation. + * + * Version: @(#)vid_mga.c 1.0.3 2020/01/20 + * + * Author: Sarah Walker, + * Copyright 2008-2020 Sarah Walker. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "plat.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_svga_render.h" + + +#define ROM_MYSTIQUE L"roms/video/matrox/MYSTIQUE.VBI" +#define ROM_MYSTIQUE_220 L"roms/video/matrox/Myst220_66-99mhz.vbi" + +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) +#define FIFO_THRESHOLD 0xe000 + +#define WAKE_DELAY (100 * TIMER_USEC) /* 100us */ + +#define FIFO_ENTRIES (mystique->fifo_write_idx - mystique->fifo_read_idx) +#define FIFO_FULL ((mystique->fifo_write_idx - mystique->fifo_read_idx) >= (FIFO_SIZE-1)) +#define FIFO_EMPTY (mystique->fifo_read_idx == mystique->fifo_write_idx) + +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff + +#define DMA_POLL_TIME_US 100 /*100us*/ +#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ + +/*These registers are also mirrored into 0x1dxx, with the mirrored versions starting + the blitter*/ +#define REG_DWGCTL 0x1c00 +#define REG_MACCESS 0x1c04 +#define REG_MCTLWTST 0x1c08 +#define REG_ZORG 0x1c0c +#define REG_PAT0 0x1c10 +#define REG_PAT1 0x1c14 +#define REG_PLNWT 0x1c1c +#define REG_BCOL 0x1c20 +#define REG_FCOL 0x1c24 +#define REG_SRC0 0x1c30 +#define REG_SRC1 0x1c34 +#define REG_SRC2 0x1c38 +#define REG_SRC3 0x1c3c +#define REG_XYSTRT 0x1c40 +#define REG_XYEND 0x1c44 +#define REG_SHIFT 0x1c50 +#define REG_DMAPAD 0x1c54 +#define REG_SGN 0x1c58 +#define REG_LEN 0x1c5c +#define REG_AR0 0x1c60 +#define REG_AR1 0x1c64 +#define REG_AR2 0x1c68 +#define REG_AR3 0x1c6c +#define REG_AR4 0x1c70 +#define REG_AR5 0x1c74 +#define REG_AR6 0x1c78 +#define REG_CXBNDRY 0x1c80 +#define REG_FXBNDRY 0x1c84 +#define REG_YDSTLEN 0x1c88 +#define REG_PITCH 0x1c8c +#define REG_YDST 0x1c90 +#define REG_YDSTORG 0x1c94 +#define REG_YTOP 0x1c98 +#define REG_YBOT 0x1c9c +#define REG_CXLEFT 0x1ca0 +#define REG_CXRIGHT 0x1ca4 +#define REG_FXLEFT 0x1ca8 +#define REG_FXRIGHT 0x1cac +#define REG_XDST 0x1cb0 +#define REG_DR0 0x1cc0 +#define REG_DR2 0x1cc8 +#define REG_DR3 0x1ccc +#define REG_DR4 0x1cd0 +#define REG_DR6 0x1cd8 +#define REG_DR7 0x1cdc +#define REG_DR8 0x1ce0 +#define REG_DR10 0x1ce8 +#define REG_DR11 0x1cec +#define REG_DR12 0x1cf0 +#define REG_DR14 0x1cf8 +#define REG_DR15 0x1cfc + +#define REG_FIFOSTATUS 0x1e10 +#define REG_STATUS 0x1e14 +#define REG_ICLEAR 0x1e18 +#define REG_IEN 0x1e1c +#define REG_VCOUNT 0x1e20 +#define REG_DMAMAP 0x1e30 +#define REG_RST 0x1e40 +#define REG_OPMODE 0x1e54 +#define REG_PRIMADDRESS 0x1e58 +#define REG_PRIMEND 0x1e5c +#define REG_DWG_INDIR_WT 0x1e80 + +#define REG_ATTR_IDX 0x1fc0 +#define REG_ATTR_DATA 0x1fc1 +#define REG_INSTS0 0x1fc2 +#define REG_MISC 0x1fc2 +#define REG_SEQ_IDX 0x1fc4 +#define REG_SEQ_DATA 0x1fc5 +#define REG_MISCREAD 0x1fcc +#define REG_GCTL_IDX 0x1fce +#define REG_GCTL_DATA 0x1fcf +#define REG_CRTC_IDX 0x1fd4 +#define REG_CRTC_DATA 0x1fd5 +#define REG_INSTS1 0x1fda +#define REG_CRTCEXT_IDX 0x1fde +#define REG_CRTCEXT_DATA 0x1fdf +#define REG_CACHEFLUSH 0x1fff + +#define REG_TMR0 0x2c00 +#define REG_TMR1 0x2c04 +#define REG_TMR2 0x2c08 +#define REG_TMR3 0x2c0c +#define REG_TMR4 0x2c10 +#define REG_TMR5 0x2c14 +#define REG_TMR6 0x2c18 +#define REG_TMR7 0x2c1c +#define REG_TMR8 0x2c20 +#define REG_TEXORG 0x2c24 +#define REG_TEXWIDTH 0x2c28 +#define REG_TEXHEIGHT 0x2c2c +#define REG_TEXCTL 0x2c30 +#define REG_TEXTRANS 0x2c34 +#define REG_SECADDRESS 0x2c40 +#define REG_SECEND 0x2c44 +#define REG_SOFTRAP 0x2c48 + +#define REG_PALWTADD 0x3c00 +#define REG_PALDATA 0x3c01 +#define REG_PIXRDMSK 0x3c02 +#define REG_PALRDADD 0x3c03 +#define REG_X_DATAREG 0x3c0a +#define REG_CURPOSX 0x3c0c +#define REG_CURPOSY 0x3c0e + +#define REG_STATUS_VSYNCSTS (1 << 3) + +#define CRTCX_R0_STARTADD_MASK (0xf << 0) +#define CRTCX_R0_OFFSET_MASK (3 << 4) + +#define CRTCX_R1_HTOTAL8 (1 << 0) + +#define CRTCX_R2_VTOTAL10 (1 << 0) +#define CRTCX_R2_VTOTAL11 (1 << 1) +#define CRTCX_R2_VDISPEND10 (1 << 2) +#define CRTCX_R2_VBLKSTR10 (1 << 3) +#define CRTCX_R2_VBLKSTR11 (1 << 4) +#define CRTCX_R2_VSYNCSTR10 (1 << 5) +#define CRTCX_R2_VSYNCSTR11 (1 << 6) +#define CRTCX_R2_LINECOMP10 (1 << 7) + +#define CRTCX_R3_MGAMODE (1 << 7) + +#define XREG_XCURADDL 0x04 +#define XREG_XCURADDH 0x05 +#define XREG_XCURCTRL 0x06 + +#define XREG_XCURCOL0R 0x08 +#define XREG_XCURCOL0G 0x09 +#define XREG_XCURCOL0B 0x0a + +#define XREG_XCURCOL1R 0x0c +#define XREG_XCURCOL1G 0x0d +#define XREG_XCURCOL1B 0x0e + +#define XREG_XCURCOL2R 0x10 +#define XREG_XCURCOL2G 0x11 +#define XREG_XCURCOL2B 0x12 + +#define XREG_XVREFCTRL 0x18 +#define XREG_XMULCTRL 0x19 +#define XREG_XPIXCLKCTRL 0x1a +#define XREG_XGENCTRL 0x1d +#define XREG_XMISCCTRL 0x1e + +#define XREG_XGENIOCTRL 0x2a +#define XREG_XGENIODATA 0x2b + +#define XREG_XSYSPLLM 0x2c +#define XREG_XSYSPLLN 0x2d +#define XREG_XSYSPLLP 0x2e +#define XREG_XSYSPLLSTAT 0x2f + +#define XREG_XZOOMCTRL 0x38 + +#define XREG_XPIXPLLCM 0x4c +#define XREG_XPIXPLLCN 0x4d +#define XREG_XPIXPLLCP 0x4e +#define XREG_XPIXPLLSTAT 0x4f + +#define XMISCCTRL_VGA8DAC (1 << 3) + +#define XMULCTRL_DEPTH_MASK (7 << 0) +#define XMULCTRL_DEPTH_8 (0 << 0) +#define XMULCTRL_DEPTH_15 (1 << 0) +#define XMULCTRL_DEPTH_16 (2 << 0) +#define XMULCTRL_DEPTH_24 (3 << 0) +#define XMULCTRL_DEPTH_32_OVERLAYED (4 << 0) +#define XMULCTRL_DEPTH_2G8V16 (5 << 0) +#define XMULCTRL_DEPTH_G16V16 (6 << 0) +#define XMULCTRL_DEPTH_32 (7 << 0) + +#define XSYSPLLSTAT_SYSLOCK (1 << 6) + +#define XPIXPLLSTAT_SYSLOCK (1 << 6) + +#define DWGCTRL_OPCODE_MASK (0xf << 0) +#define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0) +#define DWGCTRL_OPCODE_AUTOLINE_OPEN (0x1 << 0) +#define DWGCTRL_OPCODE_AUTOLINE_CLOSE (0x3 << 0) +#define DWGCTRL_OPCODE_TRAP (0x4 << 0) +#define DWGCTRL_OPCODE_TEXTURE_TRAP (0x6 << 0) +#define DWGCTRL_OPCODE_ILOAD_HIGH (0x7 << 0) +#define DWGCTRL_OPCODE_BITBLT (0x8 << 0) +#define DWGCTRL_OPCODE_ILOAD (0x9 << 0) +#define DWGCTRL_OPCODE_IDUMP (0xa << 0) +#define DWGCTRL_OPCODE_ILOAD_SCALE (0xd << 0) +#define DWGCTRL_OPCODE_ILOAD_HIGHV (0xe << 0) +#define DWGCTRL_OPCODE_ILOAD_FILTER (0xf << 0) /* Not implemented. */ +#define DWGCTRL_ATYPE_MASK (7 << 4) +#define DWGCTRL_ATYPE_RPL (0 << 4) +#define DWGCTRL_ATYPE_RSTR (1 << 4) +#define DWGCTRL_ATYPE_ZI (3 << 4) +#define DWGCTRL_ATYPE_BLK (4 << 4) +#define DWGCTRL_ATYPE_I (7 << 4) +#define DWGCTRL_LINEAR (1 << 7) +#define DWGCTRL_ZMODE_MASK (7 << 8) +#define DWGCTRL_ZMODE_NOZCMP (0 << 8) +#define DWGCTRL_ZMODE_ZE (2 << 8) +#define DWGCTRL_ZMODE_ZNE (3 << 8) +#define DWGCTRL_ZMODE_ZLT (4 << 8) +#define DWGCTRL_ZMODE_ZLTE (5 << 8) +#define DWGCTRL_ZMODE_ZGT (6 << 8) +#define DWGCTRL_ZMODE_ZGTE (7 << 8) +#define DWGCTRL_SOLID (1 << 11) +#define DWGCTRL_ARZERO (1 << 12) +#define DWGCTRL_SGNZERO (1 << 13) +#define DWGCTRL_SHTZERO (1 << 14) +#define DWGCTRL_BOP_MASK (0xf << 16) +#define DWGCTRL_TRANS_SHIFT (20) +#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) +#define DWGCTRL_BLTMOD_MASK (0xf << 25) +#define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) +#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) +#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) +#define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) +#define DWGCTRL_BLTMOD_BUYUV (0xe << 25) +#define DWGCTRL_BLTMOD_BU24RGB (0xf << 25) +#define DWGCTRL_PATTERN (1 << 29) +#define DWGCTRL_TRANSC (1 << 30) +#define BOP(x) ((x) << 16) + +#define MACCESS_PWIDTH_MASK (3 << 0) +#define MACCESS_PWIDTH_8 (0 << 0) +#define MACCESS_PWIDTH_16 (1 << 0) +#define MACCESS_PWIDTH_32 (2 << 0) +#define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_TLUTLOAD (1 << 29) +#define MACCESS_NODITHER (1 << 30) +#define MACCESS_DIT555 (1 << 31) + +#define PITCH_MASK 0x7e0 +#define PITCH_YLIN (1 << 15) + +#define SGN_SDYDXL (1 << 0) +#define SGN_SCANLEFT (1 << 0) +#define SGN_SDXL (1 << 1) +#define SGN_SDY (1 << 2) +#define SGN_SDXR (1 << 5) + +#define DMA_ADDR_MASK 0xfffffffc +#define DMA_MODE_MASK 3 + +#define DMA_MODE_REG 0 +#define DMA_MODE_BLIT 1 +#define DMA_MODE_VECTOR 2 + +#define STATUS_SOFTRAPEN (1 << 0) +#define STATUS_VLINEPEN (1 << 5) +#define STATUS_DWGENGSTS (1 << 16) +#define STATUS_ENDPRDMASTS (1 << 17) + +#define ICLEAR_SOFTRAPICLR (1 << 0) +#define ICLEAR_VLINEICLR (1 << 5) + +#define IEN_SOFTRAPEN (1 << 0) + +#define TEXCTL_TEXFORMAT_MASK (7 << 0) +#define TEXCTL_TEXFORMAT_TW4 (0 << 0) +#define TEXCTL_TEXFORMAT_TW8 (1 << 0) +#define TEXCTL_TEXFORMAT_TW15 (2 << 0) +#define TEXCTL_TEXFORMAT_TW16 (3 << 0) +#define TEXCTL_TEXFORMAT_TW12 (4 << 0) +#define TEXCTL_PALSEL_MASK (0xf << 4) +#define TEXCTL_TPITCH_SHIFT (16) +#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_DECALCKEY (1 << 24) +#define TEXCTL_TAKEY (1 << 25) +#define TEXCTL_TAMASK (1 << 26) +#define TEXCTL_CLAMPV (1 << 27) +#define TEXCTL_CLAMPU (1 << 28) +#define TEXCTL_TMODULATE (1 << 29) +#define TEXCTL_STRANS (1 << 30) +#define TEXCTL_ITRANS (1 << 31) + +#define TEXHEIGHT_TH_MASK (0x3f << 0) +#define TEXHEIGHT_THMASK_SHIFT (18) +#define TEXHEIGHT_THMASK_MASK (0x7ff << TEXHEIGHT_THMASK_SHIFT) + +#define TEXWIDTH_TW_MASK (0x3f << 0) +#define TEXWIDTH_TWMASK_SHIFT (18) +#define TEXWIDTH_TWMASK_MASK (0x7ff << TEXWIDTH_TWMASK_SHIFT) + +#define TEXTRANS_TCKEY_MASK (0xffff) +#define TEXTRANS_TKMASK_SHIFT (16) +#define TEXTRANS_TKMASK_MASK (0xffff << TEXTRANS_TKMASK_SHIFT) + +#define DITHER_565 0 +#define DITHER_NONE_565 1 +#define DITHER_555 2 +#define DITHER_NONE_555 3 + + +enum +{ + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_CTRL_BYTE = (0x01 << 24), + FIFO_WRITE_CTRL_LONG = (0x02 << 24), + FIFO_WRITE_ILOAD_LONG = (0x03 << 24) +}; + +enum +{ + DMA_STATE_IDLE = 0, + DMA_STATE_PRI, + DMA_STATE_SEC +}; + + +typedef struct +{ + uint32_t addr_type; + uint32_t val; +} fifo_entry_t; + +typedef struct mystique_t +{ + svga_t svga; + + rom_t bios_rom; + + mem_mapping_t lfb_mapping, ctrl_mapping, + iload_mapping; + + uint8_t int_line, xcurctrl, + xsyspllm, xsysplln, xsyspllp, + xgenioctrl, xgeniodata, + xmulctrl, xgenctrl, + xmiscctrl, xpixclkctrl, + xvrefctrl, ien, dmamod, + dmadatasiz, dirdatasiz; + + uint8_t pci_regs[256], crtcext_regs[6], + xreg_regs[256], dmamap[16]; + + int card, vram_size, crtcext_idx, xreg_idx, + xzoomctrl, + pixel_count, trap_count; + + volatile int busy, blitter_submit_refcount, + blitter_submit_dma_refcount, blitter_complete_refcount, + endprdmasts_pending, softrap_pending, + fifo_read_idx, fifo_write_idx; + + uint32_t vram_mask, vram_mask_w, vram_mask_l, + lfb_base, ctrl_base, iload_base, + ma_latch_old, maccess, mctlwtst, maccess_running, + status, softrap_pending_val; + + uint64_t blitter_time, status_time; + + pc_timer_t softrap_pending_timer, wake_timer; + + fifo_entry_t fifo[FIFO_SIZE]; + + thread_t *fifo_thread; + + event_t *wake_fifo_thread, *fifo_not_full_event; + + struct + { + int m, n, p, s; + } xpixpll[3]; + + struct + { + uint8_t funcnt, stylelen, + dmamod; + + int16_t fxleft, fxright, + xdst; + + uint16_t cxleft, cxright, + length; + + int xoff, yoff, selline, ydst, + length_cur, iload_rem_count, idump_end_of_line, words, + ta_key, ta_mask, lastpix_r, lastpix_g, + lastpix_b, highv_line, beta, dither; + + int pattern[8][8]; + + uint32_t dwgctrl, dwgctrl_running, bcol, fcol, + pitch, plnwt, ybot, ydstorg, + ytop, texorg, texwidth, texheight, + texctl, textrans, zorg, ydst_lin, + src_addr, z_base, iload_rem_data, highv_data; + + uint32_t src[4], ar[7], + dr[16], tmr[9]; + + struct + { + int sdydxl, scanleft, sdxl, sdy, + sdxr; + } sgn; + } dwgreg; + + struct + { + uint8_t r, g, b; + } lut[256]; + + struct + { + uint16_t pos_x, pos_y, + addr; + uint32_t col[3]; + } cursor; + + struct + { + int pri_pos, sec_pos, iload_pos, + pri_state, sec_state, iload_state, state; + + uint32_t primaddress, primend, secaddress, secend, + pri_header, sec_header, + iload_header; + + mutex_t *lock; + } dma; +} mystique_t; + + +static const uint8_t trans_masks[16][16] = +{ + { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 + }, + { + 1, 0, 1, 0, + 0, 1, 0, 1, + 1, 0, 1, 0, + 0, 1, 0, 1 + }, + { + 0, 1, 0, 1, + 1, 0, 1, 0, + 0, 1, 0, 1, + 1, 0, 1, 0 + }, + { + 1, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 1, 0, + 0, 0, 0, 0 + }, + { + 0, 1, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 1, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 1, 0 + }, + { + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 1 + }, + { + 1, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1 + }, + { + 0, 0, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0 + }, + { + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 0 + }, + { + 0, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + } +}; + + +static int8_t dither5[256][2][2]; +static int8_t dither6[256][2][2]; + +static video_timings_t timing_matrox_mystique = {VIDEO_BUS, 4, 4, 4, 10, 10, 10}; + + +static void mystique_start_blit(mystique_t *mystique); +static void mystique_update_irqs(mystique_t *mystique); + +static void wake_fifo_thread(mystique_t *mystique); +static void wait_fifo_idle(mystique_t *mystique); +static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); + +static uint8_t mystique_readb_linear(uint32_t addr, void *p); +static uint16_t mystique_readw_linear(uint32_t addr, void *p); +static uint32_t mystique_readl_linear(uint32_t addr, void *p); +static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p); +static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p); +static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p); + +static void mystique_recalc_mapping(mystique_t *mystique); +static int mystique_line_compare(svga_t *svga); + +static uint8_t mystique_iload_read_b(uint32_t addr, void *p); +static uint32_t mystique_iload_read_l(uint32_t addr, void *p); +static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p); +static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p); + +static uint32_t blit_idump_read(mystique_t *mystique); +static void blit_iload_write(mystique_t *mystique, uint32_t data, int size); + + +void +mystique_out(uint16_t addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t old; + + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c8: + mystique->xreg_idx = val; + break; + + case 0x3cf: + if ((svga->gdcaddr & 15) == 6 && svga->gdcreg[6] != val) { + svga->gdcreg[svga->gdcaddr & 15] = val; + mystique_recalc_mapping(mystique); + return; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) + return; + if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg & 0x3f]; + svga->crtc[svga->crtcreg & 31] = val; + if (old != val) { + if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + + case 0x3de: + mystique->crtcext_idx = val; + break; + case 0x3df: + if (mystique->crtcext_idx < 6) + mystique->crtcext_regs[mystique->crtcext_idx] = val; + if (mystique->crtcext_idx < 4) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 3) { + if (val & CRTCX_R3_MGAMODE) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 4) { + if (svga->gdcreg[6] & 0xc) { + /*64k banks*/ + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } else { + /*128k banks*/ + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } + } + break; + } + + svga_out(addr, val, svga); +} + + +uint8_t +mystique_in(uint16_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t temp = 0xff; + + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg & 0x3f]; + break; + + case 0x3df: + if (mystique->crtcext_idx < 6) + temp = mystique->crtcext_regs[mystique->crtcext_idx]; + break; + + default: + temp = svga_in(addr, svga); + break; + } + + return temp; +} + + +static int +mystique_line_compare(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *)svga->p; + + mystique->status |= STATUS_VLINEPEN; + mystique_update_irqs(mystique); + + return 0; +} + + +void +mystique_recalctimings(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *)svga->p; + int clk_sel = (svga->miscout >> 2) & 3; + + if (clk_sel & 2) { + int m = mystique->xpixpll[2].m; + int n = mystique->xpixpll[2].n; + int p = mystique->xpixpll[2].p; + + double fvco = 14318181.0 * (n + 1) / (m + 1); + double fo = fvco / (p + 1); + + svga->clock = (cpuclock * (float)(1ull << 32)) / fo; + } + + if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) + svga->htotal += 0x100; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) + svga->vtotal += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) + svga->vtotal += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) + svga->dispend += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) + svga->vblankstart += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) + svga->vblankstart += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) + svga->vsyncstart += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) + svga->vsyncstart += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) + svga->split += 0x400; + + svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); + + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + int row_offset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + + svga->lowres = 0; + svga->char_width = 8; + svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp_time = svga->hdisp; + if (svga->interlace) + svga->rowoffset = row_offset; + else + svga->rowoffset = row_offset * 2; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 17) | + (svga->crtc[0xc] << 9) | (svga->crtc[0xd] << 1); + + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; + } + + svga->line_compare = mystique_line_compare; + + mem_mapping_set_handler(&mystique->lfb_mapping, + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear); + } else { + svga->line_compare = NULL; + svga->bpp = 8; + + mem_mapping_set_handler(&mystique->lfb_mapping, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear); + } +} + + +static +void mystique_recalc_mapping(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + + io_removehandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + if ((mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (mystique->pci_regs[0x41] & 1)) + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + + if (!(mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mystique->ctrl_mapping); + mem_mapping_disable(&mystique->lfb_mapping); + mem_mapping_disable(&mystique->iload_mapping); + return; + } + + if (mystique->ctrl_base) + mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); + else + mem_mapping_disable(&mystique->ctrl_mapping); + + if (mystique->lfb_base) + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + else + mem_mapping_disable(&mystique->lfb_mapping); + + if (mystique->iload_base) + mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); + else + mem_mapping_disable(&mystique->iload_mapping); + + if (mystique->pci_regs[0x41] & 1) { + switch (svga->gdcreg[6] & 0x0C) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0x1ffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + if (svga->gdcreg[6] & 0xc) { + /*64k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + } else { + /*128k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + } + } else + mem_mapping_disable(&svga->mapping); +} + + +static void +mystique_update_irqs(mystique_t *mystique) +{ + int irq = 0; + + if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) + irq = 1; + + if (irq) + pci_set_irq(mystique->card, PCI_INTA); + else + pci_clear_irq(mystique->card, PCI_INTA); +} + + +#define READ8(addr, var) switch ((addr) & 3) { \ + case 0: ret = (var) & 0xff; break; \ + case 1: ret = ((var) >> 8) & 0xff; break; \ + case 2: ret = ((var) >> 16) & 0xff; break; \ + case 3: ret = ((var) >> 24) & 0xff; break; \ + } + +#define WRITE8(addr, var, val) switch ((addr) & 3) { \ + case 0: var = (var & 0xffffff00) | (val); break; \ + case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ + case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ + case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ + } + + +static uint8_t +mystique_read_xreg(mystique_t *mystique, int reg) +{ + uint8_t ret = 0xff; + + switch (reg) { + case XREG_XCURADDL: + ret = mystique->cursor.addr & 0xff; + break; + case XREG_XCURADDH: + ret = mystique->cursor.addr >> 8; + break; + case XREG_XCURCTRL: + ret = mystique->xcurctrl; + break; + + case XREG_XCURCOL0R: case XREG_XCURCOL0G: case XREG_XCURCOL0B: + READ8(reg, mystique->cursor.col[0]); + break; + case XREG_XCURCOL1R: case XREG_XCURCOL1G: case XREG_XCURCOL1B: + READ8(reg, mystique->cursor.col[1]); + break; + case XREG_XCURCOL2R: case XREG_XCURCOL2G: case XREG_XCURCOL2B: + READ8(reg, mystique->cursor.col[2]); + break; + + case XREG_XMULCTRL: + ret = mystique->xmulctrl; + break; + + case XREG_XMISCCTRL: + ret = mystique->xmiscctrl; + break; + + case XREG_XGENCTRL: + ret = mystique->xgenctrl; + break; + + case XREG_XGENIOCTRL: + ret = mystique->xgenioctrl; + break; + case XREG_XGENIODATA: + ret = mystique->xgeniodata; + break; + + case XREG_XSYSPLLM: + ret = mystique->xsyspllm; + break; + case XREG_XSYSPLLN: + ret = mystique->xsysplln; + break; + case XREG_XSYSPLLP: + ret = mystique->xsyspllp; + break; + + case XREG_XZOOMCTRL: + ret = mystique->xzoomctrl; + break; + + case XREG_XPIXCLKCTRL: + ret = mystique->xpixclkctrl; + break; + + case XREG_XSYSPLLSTAT: + ret = XSYSPLLSTAT_SYSLOCK; + break; + + case XREG_XPIXPLLSTAT: + ret = XPIXPLLSTAT_SYSLOCK; + break; + + case XREG_XPIXPLLCM: + ret = mystique->xpixpll[2].m; + break; + case XREG_XPIXPLLCN: + ret = mystique->xpixpll[2].n; + break; + case XREG_XPIXPLLCP: + ret = mystique->xpixpll[2].p | (mystique->xpixpll[2].s << 3); + break; + + case 0x00: case 0x20: case 0x3f: + ret = 0xff; + break; + + default: + if (reg >= 0x50) + ret = 0xff; + break; + } + + return ret; +} + + +static void +mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) +{ + svga_t *svga = &mystique->svga; + + switch (reg) { + case XREG_XCURADDL: + mystique->cursor.addr = (mystique->cursor.addr & 0x1f00) | val; + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; + case XREG_XCURADDH: + mystique->cursor.addr = (mystique->cursor.addr & 0x00ff) | ((val & 0x1f) << 8); + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; + + case XREG_XCURCTRL: + mystique->xcurctrl = val; + svga->hwcursor.ena = (val & 3) ? 1 : 0; + break; + + case XREG_XCURCOL0R: case XREG_XCURCOL0G: case XREG_XCURCOL0B: + WRITE8(reg, mystique->cursor.col[0], val); + break; + case XREG_XCURCOL1R: case XREG_XCURCOL1G: case XREG_XCURCOL1B: + WRITE8(reg, mystique->cursor.col[1], val); + break; + case XREG_XCURCOL2R: case XREG_XCURCOL2G: case XREG_XCURCOL2B: + WRITE8(reg, mystique->cursor.col[2], val); + break; + + case XREG_XMULCTRL: + mystique->xmulctrl = val; + break; + + case XREG_XMISCCTRL: + mystique->xmiscctrl = val; + svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; + + case XREG_XGENCTRL: + mystique->xgenctrl = val; + break; + + case XREG_XVREFCTRL: + mystique->xvrefctrl = val; + break; + + case XREG_XGENIOCTRL: + mystique->xgenioctrl = val; + break; + case XREG_XGENIODATA: + mystique->xgeniodata = val; + break; + + case XREG_XSYSPLLM: + mystique->xsyspllm = val; + break; + case XREG_XSYSPLLN: + mystique->xsysplln = val; + break; + case XREG_XSYSPLLP: + mystique->xsyspllp = val; + break; + + case XREG_XZOOMCTRL: + mystique->xzoomctrl = val & 3; + break; + + case XREG_XPIXCLKCTRL: + mystique->xpixclkctrl = val; + break; + + case XREG_XPIXPLLCM: + mystique->xpixpll[2].m = val; + break; + case XREG_XPIXPLLCN: + mystique->xpixpll[2].n = val; + break; + case XREG_XPIXPLLCP: + mystique->xpixpll[2].p = val & 7; + mystique->xpixpll[2].s = (val >> 3) & 3; + break; + + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x07: case 0x0b: case 0x0f: + case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x1b: case 0x1c: case 0x20: case 0x39: case 0x3b: case 0x3f: + case 0x47: case 0x4b: + break; + + default: + break; + } +} + + +static uint8_t +mystique_ctrl_read_b(uint32_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t ret = 0xff; + int fifocount; + + switch (addr & 0x3fff) { + case REG_FIFOSTATUS: + fifocount = FIFO_SIZE - FIFO_ENTRIES; + if (fifocount > 64) + fifocount = 64; + ret = fifocount; + break; + case REG_FIFOSTATUS+1: + if (FIFO_EMPTY) + ret |= 2; + else if (FIFO_ENTRIES >= 64) + ret |= 1; + break; + case REG_FIFOSTATUS+2: case REG_FIFOSTATUS+3: + ret = 0; + break; + + case REG_STATUS: + ret = mystique->status & 0xff; + if (svga->cgastat & 8) + ret |= REG_STATUS_VSYNCSTS; + break; + case REG_STATUS+1: + ret = (mystique->status >> 8) & 0xff; + break; + case REG_STATUS+2: + ret = (mystique->status >> 16) & 0xff; + if (mystique->busy || + ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || + !FIFO_EMPTY) + ret |= (STATUS_DWGENGSTS >> 16); + break; + case REG_STATUS+3: + ret = (mystique->status >> 24) & 0xff; + break; + + case REG_IEN: + ret = mystique->ien & 0x64; + break; + case REG_IEN+1: case REG_IEN+2: case REG_IEN+3: + ret = 0; + break; + + case REG_OPMODE: + ret = mystique->dmamod << 2; + break; + case REG_OPMODE+1: + ret = mystique->dmadatasiz; + break; + case REG_OPMODE+2: + ret = mystique->dirdatasiz; + break; + case REG_OPMODE+3: + break; + + case REG_PRIMADDRESS: case REG_PRIMADDRESS+1: case REG_PRIMADDRESS+2: case REG_PRIMADDRESS+3: + READ8(addr, mystique->dma.primaddress); + break; + case REG_PRIMEND: case REG_PRIMEND+1: case REG_PRIMEND+2: case REG_PRIMEND+3: + READ8(addr, mystique->dma.primend); + break; + + case REG_SECADDRESS: case REG_SECADDRESS+1: case REG_SECADDRESS+2: case REG_SECADDRESS+3: + READ8(addr, mystique->dma.secaddress); + break; + + case REG_VCOUNT: case REG_VCOUNT+1: case REG_VCOUNT+2: case REG_VCOUNT+3: + READ8(addr, svga->vc); + break; + + case REG_ATTR_IDX: + ret = svga_in(0x3c0, svga); + break; + case REG_ATTR_DATA: + ret = svga_in(0x3c1, svga); + break; + + case REG_INSTS0: + ret = svga_in(0x3c2, svga); + break; + + case REG_SEQ_IDX: + ret = svga_in(0x3c4, svga); + break; + case REG_SEQ_DATA: + ret = svga_in(0x3c5, svga); + break; + + case REG_MISCREAD: + ret = svga_in(0x3cc, svga); + break; + + case REG_GCTL_IDX: + ret = mystique_in(0x3ce, mystique); + break; + case REG_GCTL_DATA: + ret = mystique_in(0x3cf, mystique); + break; + + case REG_CRTC_IDX: + ret = mystique_in(0x3d4, mystique); + break; + case REG_CRTC_DATA: + ret = mystique_in(0x3d5, mystique); + break; + + case REG_INSTS1: + ret = mystique_in(0x3da, mystique); + break; + + case REG_CRTCEXT_IDX: + ret = mystique_in(0x3de, mystique); + break; + case REG_CRTCEXT_DATA: + ret = mystique_in(0x3df, mystique); + break; + + case REG_PALWTADD: + ret = svga_in(0x3c8, svga); + break; + case REG_PALDATA: + ret = svga_in(0x3c9, svga); + break; + case REG_PIXRDMSK: + ret = svga_in(0x3c6, svga); + break; + case REG_PALRDADD: + ret = svga_in(0x3c7, svga); + break; + + case REG_X_DATAREG: + ret = mystique_read_xreg(mystique, mystique->xreg_idx); + break; + + case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53: + case REG_ICLEAR: case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: + case 0x2c30: case 0x2c31: case 0x2c32: case 0x2c33: + case 0x3e08: + break; + + default: + if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) + break; + if ((addr & 0x3fff) >= 0x3e00) + break; + break; + } + + return ret; +} + + +static void +mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + int start_blit = 0; + int x; + + if ((addr & 0x300) == 0x100) { + addr &= ~0x100; + start_blit = 1; + } + + switch (addr & 0x3fff) { + case REG_MACCESS: case REG_MACCESS+1: case REG_MACCESS+2: case REG_MACCESS+3: + WRITE8(addr, mystique->maccess, val); + mystique->dwgreg.dither = mystique->maccess >> 30; + break; + + case REG_MCTLWTST: case REG_MCTLWTST+1: case REG_MCTLWTST+2: case REG_MCTLWTST+3: + WRITE8(addr, mystique->mctlwtst, val); + break; + + case REG_PAT0: case REG_PAT0+1: case REG_PAT0+2: case REG_PAT0+3: + case REG_PAT1: case REG_PAT1+1: case REG_PAT1+2: case REG_PAT1+3: + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7-x)); + break; + + case REG_XYSTRT: case REG_XYSTRT+1: + WRITE8(addr&1, mystique->dwgreg.ar[5], val); + if (mystique->dwgreg.ar[5] & 0x8000) + mystique->dwgreg.ar[5] |= 0xffff8000; + else + mystique->dwgreg.ar[5] &= ~0xffff8000; + WRITE8(addr&1, mystique->dwgreg.xdst, val); + break; + case REG_XYSTRT+2: case REG_XYSTRT+3: + WRITE8(addr & 1, mystique->dwgreg.ar[6], val); + if (mystique->dwgreg.ar[6] & 0x8000) + mystique->dwgreg.ar[6] |= 0xffff8000; + else + mystique->dwgreg.ar[6] &= ~0xffff8000; + WRITE8(addr & 1, mystique->dwgreg.ydst, val); + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; + + case REG_XYEND: case REG_XYEND+1: + WRITE8(addr&1, mystique->dwgreg.ar[0], val); + if (mystique->dwgreg.ar[0] & 0x8000) + mystique->dwgreg.ar[0] |= 0xffff8000; + else + mystique->dwgreg.ar[0] &= ~0xffff8000; + break; + case REG_XYEND+2: case REG_XYEND+3: + WRITE8(addr & 1, mystique->dwgreg.ar[2], val); + if (mystique->dwgreg.ar[2] & 0x8000) + mystique->dwgreg.ar[2] |= 0xffff8000; + else + mystique->dwgreg.ar[2] &= ~0xffff8000; + break; + + case REG_SGN: + mystique->dwgreg.sgn.sdydxl = val & SGN_SDYDXL; + mystique->dwgreg.sgn.scanleft = val & SGN_SCANLEFT; + mystique->dwgreg.sgn.sdxl = val & SGN_SDXL; + mystique->dwgreg.sgn.sdy = val & SGN_SDY; + mystique->dwgreg.sgn.sdxr = val & SGN_SDXR; + break; + case REG_SGN+1: case REG_SGN+2: case REG_SGN+3: + break; + + case REG_LEN: case REG_LEN+1: + WRITE8(addr, mystique->dwgreg.length, val); + break; + case REG_LEN+2: + break; + case REG_LEN+3: + mystique->dwgreg.beta = val >> 4; + if (!mystique->dwgreg.beta) + mystique->dwgreg.beta = 16; + break; + + case REG_CXBNDRY: case REG_CXBNDRY+1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXBNDRY+2: case REG_CXBNDRY+3: + WRITE8(addr & 1, mystique->dwgreg.cxright, val); + break; + case REG_FXBNDRY: case REG_FXBNDRY+1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXBNDRY+2: case REG_FXBNDRY+3: + WRITE8(addr & 1, mystique->dwgreg.fxright, val); + break; + + case REG_YDSTLEN: case REG_YDSTLEN+1: + WRITE8(addr, mystique->dwgreg.length, val); + /* pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); */ + break; + case REG_YDSTLEN+2: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else { + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } + break; + case REG_YDSTLEN+3: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & 0xff) | (((int32_t)(int8_t)val) << 8); + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; + + case REG_XDST: case REG_XDST+1: + WRITE8(addr & 1, mystique->dwgreg.xdst, val); + break; + case REG_XDST+2: case REG_XDST+3: + break; + + case REG_YDSTORG: case REG_YDSTORG+1: case REG_YDSTORG+2: case REG_YDSTORG+3: + WRITE8(addr, mystique->dwgreg.ydstorg, val); + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg*2 + mystique->dwgreg.zorg; + break; + case REG_YTOP: case REG_YTOP+1: case REG_YTOP+2: case REG_YTOP+3: + WRITE8(addr, mystique->dwgreg.ytop, val); + break; + case REG_YBOT: case REG_YBOT+1: case REG_YBOT+2: case REG_YBOT+3: + WRITE8(addr, mystique->dwgreg.ybot, val); + break; + + case REG_CXLEFT: case REG_CXLEFT+1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXLEFT+2: case REG_CXLEFT+3: + break; + case REG_CXRIGHT: case REG_CXRIGHT+1: + WRITE8(addr, mystique->dwgreg.cxright, val); + break; + case REG_CXRIGHT+2: case REG_CXRIGHT+3: + break; + + case REG_FXLEFT: case REG_FXLEFT+1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXLEFT+2: case REG_FXLEFT+3: + break; + case REG_FXRIGHT: case REG_FXRIGHT+1: + WRITE8(addr, mystique->dwgreg.fxright, val); + break; + case REG_FXRIGHT+2: case REG_FXRIGHT+3: + break; + + case REG_SECADDRESS: case REG_SECADDRESS+1: case REG_SECADDRESS+2: case REG_SECADDRESS+3: + WRITE8(addr, mystique->dma.secaddress, val); + mystique->dma.sec_state = 0; + break; + + case REG_TMR0: case REG_TMR0+1: case REG_TMR0+2: case REG_TMR0+3: + WRITE8(addr, mystique->dwgreg.tmr[0], val); + break; + case REG_TMR1: case REG_TMR1+1: case REG_TMR1+2: case REG_TMR1+3: + WRITE8(addr, mystique->dwgreg.tmr[1], val); + break; + case REG_TMR2: case REG_TMR2+1: case REG_TMR2+2: case REG_TMR2+3: + WRITE8(addr, mystique->dwgreg.tmr[2], val); + break; + case REG_TMR3: case REG_TMR3+1: case REG_TMR3+2: case REG_TMR3+3: + WRITE8(addr, mystique->dwgreg.tmr[3], val); + break; + case REG_TMR4: case REG_TMR4+1: case REG_TMR4+2: case REG_TMR4+3: + WRITE8(addr, mystique->dwgreg.tmr[4], val); + break; + case REG_TMR5: case REG_TMR5+1: case REG_TMR5+2: case REG_TMR5+3: + WRITE8(addr, mystique->dwgreg.tmr[5], val); + break; + case REG_TMR6: case REG_TMR6+1: case REG_TMR6+2: case REG_TMR6+3: + WRITE8(addr, mystique->dwgreg.tmr[6], val); + break; + case REG_TMR7: case REG_TMR7+1: case REG_TMR7+2: case REG_TMR7+3: + WRITE8(addr, mystique->dwgreg.tmr[7], val); + break; + case REG_TMR8: case REG_TMR8+1: case REG_TMR8+2: case REG_TMR8+3: + WRITE8(addr, mystique->dwgreg.tmr[8], val); + break; + + case REG_TEXORG: case REG_TEXORG+1: case REG_TEXORG+2: case REG_TEXORG+3: + WRITE8(addr, mystique->dwgreg.texorg, val); + break; + case REG_TEXWIDTH: case REG_TEXWIDTH+1: case REG_TEXWIDTH+2: case REG_TEXWIDTH+3: + WRITE8(addr, mystique->dwgreg.texwidth, val); + break; + case REG_TEXHEIGHT: case REG_TEXHEIGHT+1: case REG_TEXHEIGHT+2: case REG_TEXHEIGHT+3: + WRITE8(addr, mystique->dwgreg.texheight, val); + break; + case REG_TEXCTL: case REG_TEXCTL+1: case REG_TEXCTL+2: case REG_TEXCTL+3: + WRITE8(addr, mystique->dwgreg.texctl, val); + mystique->dwgreg.ta_key = (mystique->dwgreg.texctl & TEXCTL_TAKEY) ? 1 : 0; + mystique->dwgreg.ta_mask = (mystique->dwgreg.texctl & TEXCTL_TAMASK) ? 1 : 0; + break; + case REG_TEXTRANS: case REG_TEXTRANS+1: case REG_TEXTRANS+2: case REG_TEXTRANS+3: + WRITE8(addr, mystique->dwgreg.textrans, val); + break; + + case 0x1c28: case 0x1c29: case 0x1c2a: case 0x1c2b: + case 0x1c2c: case 0x1c2d: case 0x1c2e: case 0x1c2f: + case 0x1cc4: case 0x1cc5: case 0x1cc6: case 0x1cc7: + case 0x1cd4: case 0x1cd5: case 0x1cd6: case 0x1cd7: + case 0x1ce4: case 0x1ce5: case 0x1ce6: case 0x1ce7: + case 0x1cf4: case 0x1cf5: case 0x1cf6: case 0x1cf7: + break; + + case REG_OPMODE: + mystique->dwgreg.dmamod = (val >> 2) & 3; + mystique->dma.iload_state = 0; + break; + + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + break; + } + + if (start_blit) + mystique_start_blit(mystique); +} + + +static void +mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + + if ((addr & 0x3fff) < 0x1c00) { + mystique_iload_write_b(addr, val, p); + return; + } + if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + return; + } + + switch (addr & 0x3fff) { + case REG_ICLEAR: + if (val & ICLEAR_SOFTRAPICLR) { + mystique->status &= ~STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } + if (val & ICLEAR_VLINEICLR) { + mystique->status &= ~STATUS_VLINEPEN; + mystique_update_irqs(mystique); + } + break; + case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: + break; + + case REG_IEN: + mystique->ien = val & 0x65; + break; + case REG_IEN+1: case REG_IEN+2: case REG_IEN+3: + break; + + case REG_OPMODE: + mystique->dmamod = (val >> 2) & 3; + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + break; + case REG_OPMODE+1: + mystique->dmadatasiz = val & 3; + break; + case REG_OPMODE+2: + mystique->dirdatasiz = val & 3; + break; + case REG_OPMODE+3: + break; + + case REG_PRIMADDRESS: case REG_PRIMADDRESS+1: case REG_PRIMADDRESS+2: case REG_PRIMADDRESS+3: + thread_wait_mutex(mystique->dma.lock); + WRITE8(addr, mystique->dma.primaddress, val); + mystique->dma.pri_state = 0; + thread_release_mutex(mystique->dma.lock); + break; + + case REG_DMAMAP: case REG_DMAMAP+0x1: case REG_DMAMAP+0x2: case REG_DMAMAP+0x3: + case REG_DMAMAP+0x4: case REG_DMAMAP+0x5: case REG_DMAMAP+0x6: case REG_DMAMAP+0x7: + case REG_DMAMAP+0x8: case REG_DMAMAP+0x9: case REG_DMAMAP+0xa: case REG_DMAMAP+0xb: + case REG_DMAMAP+0xc: case REG_DMAMAP+0xd: case REG_DMAMAP+0xe: case REG_DMAMAP+0xf: + mystique->dmamap[addr & 0xf] = val; + break; + + case REG_RST: case REG_RST+1: case REG_RST+2: case REG_RST+3: + wait_fifo_idle(mystique); + mystique->busy = 0; + mystique->blitter_submit_refcount = 0; + mystique->blitter_submit_dma_refcount = 0; + mystique->blitter_complete_refcount = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->status = STATUS_ENDPRDMASTS; + break; + + case REG_ATTR_IDX: + svga_out(0x3c0, val, svga); + break; + case REG_ATTR_DATA: + svga_out(0x3c1, val, svga); + break; + + case REG_MISC: + svga_out(0x3c2, val, svga); + break; + + case REG_SEQ_IDX: + svga_out(0x3c4, val, svga); + break; + case REG_SEQ_DATA: + svga_out(0x3c5, val, svga); + break; + + case REG_GCTL_IDX: + mystique_out(0x3ce, val, mystique); + break; + case REG_GCTL_DATA: + mystique_out(0x3cf, val, mystique); + break; + + case REG_CRTC_IDX: + mystique_out(0x3d4, val, mystique); + break; + case REG_CRTC_DATA: + mystique_out(0x3d5, val, mystique); + break; + + case REG_CRTCEXT_IDX: + mystique_out(0x3de, val, mystique); + break; + case REG_CRTCEXT_DATA: + mystique_out(0x3df, val, mystique); + break; + + case REG_CACHEFLUSH: + break; + + case REG_PALWTADD: + svga_out(0x3c8, val, svga); + mystique->xreg_idx = val; + break; + case REG_PALDATA: + svga_out(0x3c9, val, svga); + break; + case REG_PIXRDMSK: + svga_out(0x3c6, val, svga); + break; + case REG_PALRDADD: + svga_out(0x3c7, val, svga); + break; + + case REG_X_DATAREG: + mystique_write_xreg(mystique, mystique->xreg_idx, val); + break; + + case REG_CURPOSX: case REG_CURPOSX+1: + WRITE8(addr, mystique->cursor.pos_x, val); + svga->hwcursor.x = mystique->cursor.pos_x - 64; + break; + case REG_CURPOSY: case REG_CURPOSY+1: + WRITE8(addr & 1, mystique->cursor.pos_y, val); + svga->hwcursor.y = mystique->cursor.pos_y - 64; + break; + + case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53: + case 0x3c0b: case 0x3e02: case 0x3e08: + break; + + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + if ((addr & 0x3fff) >= 0x3e00) + break; + break; + } +} + + +static uint32_t +mystique_ctrl_read_l(uint32_t addr, void *p) +{ + uint32_t ret; + + if ((addr & 0x3fff) < 0x1c00) + return mystique_iload_read_l(addr, p); + + ret = mystique_ctrl_read_b(addr, p); + ret |= mystique_ctrl_read_b(addr+1, p) << 8; + ret |= mystique_ctrl_read_b(addr+2, p) << 16; + ret |= mystique_ctrl_read_b(addr+3, p) << 24; + + return ret; +} + + +static void +mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + int start_blit = 0; + + if ((addr & 0x300) == 0x100) { + addr &= ~0x100; + start_blit = 1; + } + + switch (addr & 0x3ffc) { + case REG_DWGCTL: + mystique->dwgreg.dwgctrl = val; + break; + + case REG_ZORG: + mystique->dwgreg.zorg = val; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg*2 + mystique->dwgreg.zorg; + break; + + case REG_PLNWT: + mystique->dwgreg.plnwt = val; + break; + + case REG_SHIFT: + mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.xoff = val & 7; + mystique->dwgreg.yoff = (val >> 4) & 7; + mystique->dwgreg.stylelen = (val >> 16) & 0xff; + break; + + case REG_PITCH: + mystique->dwgreg.pitch = val & 0xffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; + + case REG_YDST: + mystique->dwgreg.ydst = val & 0x3fffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) { + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val >> 29; + } else { + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } + break; + case REG_BCOL: + mystique->dwgreg.bcol = val; + break; + case REG_FCOL: + mystique->dwgreg.fcol = val; + break; + + case REG_SRC0: + mystique->dwgreg.src[0] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[0], 32); + break; + case REG_SRC1: + mystique->dwgreg.src[1] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[1], 32); + break; + case REG_SRC2: + mystique->dwgreg.src[2] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[2], 32); + break; + case REG_SRC3: + mystique->dwgreg.src[3] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[3], 32); + break; + + case REG_DMAPAD: + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[0], 32); + break; + + case REG_AR0: + mystique->dwgreg.ar[0] = val; + break; + case REG_AR1: + mystique->dwgreg.ar[1] = val; + break; + case REG_AR2: + mystique->dwgreg.ar[2] = val; + break; + case REG_AR3: + mystique->dwgreg.ar[3] = val; + break; + case REG_AR4: + mystique->dwgreg.ar[4] = val; + break; + case REG_AR5: + mystique->dwgreg.ar[5] = val; + break; + case REG_AR6: + mystique->dwgreg.ar[6] = val; + break; + + case REG_DR0: + mystique->dwgreg.dr[0] = val; + break; + case REG_DR2: + mystique->dwgreg.dr[2] = val; + break; + case REG_DR3: + mystique->dwgreg.dr[3] = val; + break; + case REG_DR4: + mystique->dwgreg.dr[4] = val; + break; + case REG_DR6: + mystique->dwgreg.dr[6] = val; + break; + case REG_DR7: + mystique->dwgreg.dr[7] = val; + break; + case REG_DR8: + mystique->dwgreg.dr[8] = val; + break; + case REG_DR10: + mystique->dwgreg.dr[10] = val; + break; + case REG_DR11: + mystique->dwgreg.dr[11] = val; + break; + case REG_DR12: + mystique->dwgreg.dr[12] = val; + break; + case REG_DR14: + mystique->dwgreg.dr[14] = val; + break; + case REG_DR15: + mystique->dwgreg.dr[15] = val; + break; + + case REG_SECEND: + mystique->dma.secend = val; + if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) + mystique->dma.state = DMA_STATE_SEC; + break; + + case REG_SOFTRAP: + mystique->dma.state = DMA_STATE_IDLE; + mystique->endprdmasts_pending = 1; + mystique->softrap_pending_val = val; + mystique->softrap_pending = 1; + break; + + default: + mystique_accel_ctrl_write_b(addr, val & 0xff, p); + mystique_accel_ctrl_write_b(addr+1, (val >> 8) & 0xff, p); + mystique_accel_ctrl_write_b(addr+2, (val >> 16) & 0xff, p); + mystique_accel_ctrl_write_b(addr+3, (val >> 24) & 0xff, p); + break; + } + + if (start_blit) + mystique_start_blit(mystique); +} + + +static void +mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + uint32_t reg_addr; + + if ((addr & 0x3fff) < 0x1c00) { + mystique_iload_write_l(addr, val, p); + return; + } + + if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_LONG); + return; + } + + switch (addr & 0x3ffc) { + case REG_PRIMEND: + thread_wait_mutex(mystique->dma.lock); + mystique->dma.primend = val; + if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 0; + mystique->status &= ~STATUS_ENDPRDMASTS; + + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.pri_state = 0; + wake_fifo_thread(mystique); + } + thread_release_mutex(mystique->dma.lock); + break; + + case REG_DWG_INDIR_WT: case REG_DWG_INDIR_WT+0x04: case REG_DWG_INDIR_WT+0x08: case REG_DWG_INDIR_WT+0x0c: + case REG_DWG_INDIR_WT+0x10: case REG_DWG_INDIR_WT+0x14: case REG_DWG_INDIR_WT+0x18: case REG_DWG_INDIR_WT+0x1c: + case REG_DWG_INDIR_WT+0x20: case REG_DWG_INDIR_WT+0x24: case REG_DWG_INDIR_WT+0x28: case REG_DWG_INDIR_WT+0x2c: + case REG_DWG_INDIR_WT+0x30: case REG_DWG_INDIR_WT+0x34: case REG_DWG_INDIR_WT+0x38: case REG_DWG_INDIR_WT+0x3c: + reg_addr = (mystique->dmamap[(addr >> 2) & 0xf] & 0x7f) << 2; + if (mystique->dmamap[(addr >> 2) & 0xf] & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + + mystique_queue(mystique, reg_addr, val, FIFO_WRITE_CTRL_LONG); + break; + + default: + mystique_ctrl_write_b(addr, val & 0xff, p); + mystique_ctrl_write_b(addr+1, (val >> 8) & 0xff, p); + mystique_ctrl_write_b(addr+2, (val >> 16) & 0xff, p); + mystique_ctrl_write_b(addr+3, (val >> 24) & 0xff, p); + break; + } +} + + +static uint8_t +mystique_iload_read_b(uint32_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + wait_fifo_idle(mystique); + + if (!mystique->busy) + return 0xff; + + return blit_idump_read(mystique); +} + + +static uint32_t +mystique_iload_read_l(uint32_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + wait_fifo_idle(mystique); + + if (!mystique->busy) + return 0xffffffff; + + mystique->dwgreg.words++; + return blit_idump_read(mystique); +} + + +static void +mystique_iload_write_b(uint32_t addr, uint8_t val, void *p) +{ + +} + + +static void +mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); +} + +static void +mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + switch (mystique->dwgreg.dmamod) { + case DMA_MODE_REG: + if (mystique->dma.iload_state == 0) { + mystique->dma.iload_header = val; + mystique->dma.iload_state = 1; + } else { + uint32_t reg_addr = (mystique->dma.iload_header & 0x7f) << 2; + if (mystique->dma.iload_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + + mystique->dma.iload_header >>= 8; + mystique->dma.iload_state = (mystique->dma.iload_state == 4) ? 0 : (mystique->dma.iload_state+1); + } + break; + + case DMA_MODE_BLIT: + if (!mystique->busy) + fatal("mystique_iload_write_l: !busy\n"); + blit_iload_write(mystique, val, 32); + break; + + /* default: + pclog("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); */ + } +} + +static uint8_t mystique_readb_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + egareads++; + + sub_cycles(video_timing_read_b); + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + return svga->vram[addr & svga->vram_mask]; +} +static uint16_t mystique_readw_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + egareads += 2; + + sub_cycles(video_timing_read_w); + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; + + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; +} +static uint32_t mystique_readl_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + egareads += 4; + + sub_cycles(video_timing_read_l); + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; + + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; +} + +static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + egawrites++; + + sub_cycles(video_timing_write_b); + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr] = val; +} +static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + egawrites += 2; + + sub_cycles(video_timing_write_w); + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; +} +static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + egawrites += 4; + + sub_cycles(video_timing_write_l); + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; +} + + +static void +run_dma(mystique_t *mystique) +{ + int words_transferred = 0; + + thread_wait_mutex(mystique->dma.lock); + + if (mystique->dma.state == DMA_STATE_IDLE) { + thread_release_mutex(mystique->dma.lock); + return; + } + + while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { + switch (mystique->dma.state) { + case DMA_STATE_PRI: + switch (mystique->dma.primaddress & DMA_MODE_MASK) { + case DMA_MODE_REG: + if (mystique->dma.pri_state == 0) { + mystique->dma.pri_header = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; + mystique->dma.primaddress += 4; + } + + if ((mystique->dma.pri_header & 0xff) != 0x15) { + uint32_t val = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; + uint32_t reg_addr; + + mystique->dma.primaddress += 4; + + reg_addr = (mystique->dma.pri_header & 0x7f) << 2; + if (mystique->dma.pri_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + } + + mystique->dma.pri_header >>= 8; + mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; + + words_transferred++; + if (mystique->dma.state == DMA_STATE_SEC) + mystique->dma.pri_state = 0; + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } + break; + + default: + fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + } + break; + + case DMA_STATE_SEC: + switch (mystique->dma.secaddress & DMA_MODE_MASK) { + case DMA_MODE_REG: + if (mystique->dma.sec_state == 0) { + mystique->dma.sec_header = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + mystique->dma.secaddress += 4; + } + + uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + uint32_t reg_addr; + + mystique->dma.secaddress += 4; + + reg_addr = (mystique->dma.sec_header & 0x7f) << 2; + if (mystique->dma.sec_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + + mystique->dma.sec_header >>= 8; + mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; + + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } else + mystique->dma.state = DMA_STATE_PRI; + } + break; + + case DMA_MODE_BLIT: { + uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + mystique->dma.secaddress += 4; + + if (!mystique->busy) + fatal("mystique_iload_write_l: !busy\n"); + + blit_iload_write(mystique, val, 32); + + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } else + mystique->dma.state = DMA_STATE_PRI; + } + } break; + + default: + fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + } + break; + } + } + + thread_release_mutex(mystique->dma.lock); +} + + +static void +fifo_thread(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + while (1) { + thread_set_event(mystique->fifo_not_full_event); + thread_wait_event(mystique->wake_fifo_thread, -1); + thread_reset_event(mystique->wake_fifo_thread); + + while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { + int words_transferred = 0; + + while (!FIFO_EMPTY && words_transferred < 100) { + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; + + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_CTRL_BYTE: + mystique_accel_ctrl_write_b(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_CTRL_LONG: + mystique_accel_ctrl_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_ILOAD_LONG: + mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + } + + fifo->addr_type = FIFO_INVALID; + mystique->fifo_read_idx++; + + if (FIFO_ENTRIES > FIFO_THRESHOLD) + thread_set_event(mystique->fifo_not_full_event); + + words_transferred++; + } + + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); + } + } +} + + +static void +wake_fifo_thread(mystique_t *mystique) +{ + if (!timer_is_enabled(&mystique->wake_timer)) { + /* Don't wake FIFO thread immediately - if we do that it will probably + process one word and go back to sleep, requiring it to be woken on + almost every write. Instead, wait a short while so that the CPU + emulation writes more data so we have more batched-up work. */ + timer_set_delay_u64(&mystique->wake_timer, WAKE_DELAY); + } +} + + +static void +wake_fifo_thread_now(mystique_t *mystique) +{ + thread_set_event(mystique->wake_fifo_thread); +} + + +static void +mystique_wake_timer(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + thread_set_event(mystique->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} + + +static void +wait_fifo_idle(mystique_t *mystique) +{ + while (!FIFO_EMPTY) { + wake_fifo_thread_now(mystique); + thread_wait_event(mystique->fifo_not_full_event, 1); + } +} + + +/*IRQ code (PCI & PIC) is not currently thread safe. SOFTRAP IRQ requests must + therefore be submitted from the main emulation thread, in this case via a timer + callback. End-of-DMA status is also deferred here to prevent races between + SOFTRAP IRQs and code reading the status register. Croc will get into an IRQ + loop and triple fault if the ENDPRDMASTS flag is seen before the IRQ is taken*/ +static void mystique_softrap_pending_timer(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); + + if (mystique->endprdmasts_pending) { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; + } + if (mystique->softrap_pending) { + mystique->softrap_pending = 0; + + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } +} + + +static +void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type) +{ + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_write_idx & FIFO_MASK]; + + if (FIFO_FULL) { + thread_reset_event(mystique->fifo_not_full_event); + if (FIFO_FULL) + thread_wait_event(mystique->fifo_not_full_event, -1); /* Wait for room in ringbuffer */ + } + + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + mystique->fifo_write_idx++; + + if (FIFO_ENTRIES > FIFO_THRESHOLD || FIFO_ENTRIES < 8) + wake_fifo_thread(mystique); +} + + +static uint32_t +bitop(uint32_t src, uint32_t dst, uint32_t dwgctrl) +{ + switch (dwgctrl & DWGCTRL_BOP_MASK) { + case BOP(0x0): return 0; + case BOP(0x1): return ~(dst | src); + case BOP(0x2): return dst & ~src; + case BOP(0x3): return ~src; + case BOP(0x4): return ~dst & src; + case BOP(0x5): return ~dst; + case BOP(0x6): return dst ^ src; + case BOP(0x7): return ~(dst & src); + case BOP(0x8): return dst & src; + case BOP(0x9): return ~(dst ^ src); + case BOP(0xa): return dst; + case BOP(0xb): return dst | ~src; + case BOP(0xc): return src; + case BOP(0xd): return ~dst | src; + case BOP(0xe): return dst | src; + case BOP(0xf): return ~0; + } + + return 0; +} + + +static uint16_t +dither(mystique_t *mystique, int r, int g, int b, int x, int y) +{ + switch (mystique->dwgreg.dither) { + case DITHER_NONE_555: + return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10); + + case DITHER_NONE_565: + return (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + + case DITHER_555: + return dither5[b][y][x] | (dither5[g][y][x] << 5) | (dither5[r][y][x] << 10); + + case DITHER_565: + default: + return dither5[b][y][x] | (dither6[g][y][x] << 5) | (dither5[r][y][x] << 11); + } +} + + +static uint32_t +blit_idump_idump(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + uint64_t val64 = 0; + uint32_t val = 0; + int count = 0; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BU32RGB: + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + while (count < 32) { + val |= (svga->vram[mystique->dwgreg.src_addr & mystique->vram_mask] << count); + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + + count += 8; + } + break; + + case MACCESS_PWIDTH_16: + while (count < 32) { + val |= (((uint16_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_w] << count); + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + + count += 16; + } + break; + + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.idump_end_of_line) { + mystique->dwgreg.idump_end_of_line = 0; + val = mystique->dwgreg.iload_rem_data; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + + count += mystique->dwgreg.iload_rem_count; + val64 = mystique->dwgreg.iload_rem_data; + + while ((count < 32) && !mystique->dwgreg.idump_end_of_line) { + val64 |= (uint64_t)((*(uint32_t *)&svga->vram[(mystique->dwgreg.src_addr * 3) & mystique->vram_mask]) & 0xffffff) << count; + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else { + count = 32; + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else { + count = 32; + break; + } + } + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + + count += 24; + } + if (count > 32) + mystique->dwgreg.iload_rem_count = count - 32; + else + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = (uint32_t)(val64 >> 32); + val = val64 & 0xffffffff; + break; + + case MACCESS_PWIDTH_32: + val = (((uint32_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_l] << count); + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + break; + + default: + fatal("IDUMP DWGCTRL_BLTMOD_BU32RGB %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->maccess_running); + } + break; + + default: + fatal("IDUMP DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + + return val; +} + + +static uint32_t +blit_idump_read(mystique_t *mystique) +{ + uint32_t ret = 0xffffffff; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { + case DWGCTRL_OPCODE_IDUMP: + ret = blit_idump_idump(mystique); + break; + + default: + /* pclog("blit_idump_read: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); */ + break; + } + + return ret; +} + + +static void +blit_iload_iload(mystique_t *mystique, uint32_t data, int size) +{ + svga_t *svga = &mystique->svga; + uint32_t src, dst; + uint64_t data64; + int min_size = 8; + uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; + const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + bltckey &= 0xff; + bltcmsk &= 0xff; + break; + case MACCESS_PWIDTH_16: + bltckey &= 0xffff; + bltcmsk &= 0xffff; + break; + } + + mystique->dwgreg.words++; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + if (mystique->maccess_running & MACCESS_TLUTLOAD) { + while ((mystique->dwgreg.length_cur > 0) && (size >= 16)) { + uint16_t src = data & 0xffff; + + mystique->lut[mystique->dwgreg.ydst & 0xff].r = (src >> 11) << 3; + mystique->lut[mystique->dwgreg.ydst & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[mystique->dwgreg.ydst & 0xff].b = (src & 0x1f) << 3; + mystique->dwgreg.ydst++; + mystique->dwgreg.length_cur--; + data >>= 16; + size -= 16; + } + + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BFCOL: + size += mystique->dwgreg.iload_rem_count; + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + min_size = 8; + break; + case MACCESS_PWIDTH_16: + min_size = 16; + break; + case MACCESS_PWIDTH_24: + min_size = 24; + break; + case MACCESS_PWIDTH_32: + min_size = 32; + break; + } + + while (size >= min_size) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(data & 0xff, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + } + + data >>= 8; + size -= 8; + break; + + case MACCESS_PWIDTH_16: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + } + + data >>= 16; + size -= 16; + break; + + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t old_dst = *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]); + + dst = bitop(data64, old_dst, mystique->dwgreg.dwgctrl_running); + *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]) = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } + + data64 >>= 24; + size -= 24; + break; + + case MACCESS_PWIDTH_32: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } + + size = 0; + break; + + default: + fatal("ILOAD RSTR/RPL BFCOL pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + + case DWGCTRL_BLTMOD_BMONOWF: + data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); + while (size) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + ((data & 0x80000000) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + trans[mystique->dwgreg.xdst & 3]) { + uint32_t old_dst; + + src = (data & 0x80000000) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BMONOWF pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + data <<= 1; + size--; + } + break; + + case DWGCTRL_BLTMOD_BU24RGB: + size += mystique->dwgreg.iload_rem_count; + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + + while (size >= 24) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data64 & 0xffffff, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BU24RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + data64 >>= 24; + size -= 24; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + + case DWGCTRL_BLTMOD_BU32RGB: + size += mystique->dwgreg.iload_rem_count; + while (size >= 32) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BU32RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + size = 0; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + + mystique->dwgreg.iload_rem_count = size; + break; + + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); + break; + } + break; + + default: + fatal("Unknown ILOAD iload atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + + +#define CLAMP(x) do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) + + +static void +blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) +{ + svga_t *svga = &mystique->svga; + uint64_t data64 = 0; + int y0, y1; + int u, v; + int dR, dG, dB; + int r0, g0, b0; + int r1, g1, b1; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + + dR = (309*v) >> 8; + dG = (100*u + 208*v) >> 8; + dB = (516*u) >> 8; + + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + data = (b0 >> 3) | ((g0 >> 2) << 5) | ((r0 >> 3) << 11); + data |= (((b1 >> 3) | ((g1 >> 2) << 5) | ((r1 >> 3) << 11)) << 16); + size = 32; + break; + case MACCESS_PWIDTH_32: + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t)b0 << 32) | ((uint64_t)g0 << 40) | ((uint64_t)r0 << 48); + size = 64; + break; + + default: + fatal("blit_iload_iload_scale BUYUV pwidth %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + break; + + default: + fatal("blit_iload_iload_scale bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + while (size >= 16) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint16_t dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + } + + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data >>= 16; + size -= 16; + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + break; + + case MACCESS_PWIDTH_32: + while (size >= 32) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst = bitop(data64, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } + + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data64 >>= 32; + size -= 32; + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + break; + + default: + fatal("ILOAD_SCALE pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } +} + + +static void +blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) +{ + svga_t *svga = &mystique->svga; + uint32_t out_data; + int y0, y1, u, v; + int dR, dG, dB; + int r = 0, g = 0, b = 0; + int next_r = 0, next_g = 0, next_b = 0; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + + dR = (309*v) >> 8; + dG = (100*u + 208*v) >> 8; + dB = (516*u) >> 8; + + r = y0 + dR; + CLAMP(r); + g = y0 - dG; + CLAMP(g); + b = y0 + dB; + CLAMP(b); + + next_r = y1 + dR; + CLAMP(next_r); + next_g = y1 - dG; + CLAMP(next_g); + next_b = y1 + dB; + CLAMP(next_b); + + size = 32; + break; + + default: + fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + + while (size >= 16) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t dst; + int f1 = (mystique->dwgreg.ar[6] >> 12) & 0xf; + int f0 = 0x10 - f1; + int out_r = ((mystique->dwgreg.lastpix_r * f0) + (r * f1)) >> 4; + int out_g = ((mystique->dwgreg.lastpix_g * f0) + (g * f1)) >> 4; + int out_b = ((mystique->dwgreg.lastpix_b * f0) + (b * f1)) >> 4; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + out_data = (out_b >> 3) | ((out_g >> 2) << 5) | ((out_r >> 3) << 11); + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + case MACCESS_PWIDTH_32: + out_data = out_b | (out_g << 8) | (out_r << 16); + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD_SCALE_HIGH RSTR/RPL BUYUV pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= 65536; + size -= 16; + + mystique->dwgreg.lastpix_r = r; + mystique->dwgreg.lastpix_g = g; + mystique->dwgreg.lastpix_b = b; + r = next_r; + g = next_g; + b = next_b; + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; + + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } +} + + +static void +blit_iload_iload_highv(mystique_t *mystique, uint32_t data, int size) +{ + uint8_t *src0, *src1; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + if (!mystique->dwgreg.highv_line) { + mystique->dwgreg.highv_data = data; + mystique->dwgreg.highv_line = 1; + return; + } + mystique->dwgreg.highv_line = 0; + + src0 = (uint8_t *)&mystique->dwgreg.highv_data; + src1 = (uint8_t *)&data; + + src1[0] = ((src0[0] * mystique->dwgreg.beta) + (src1[0] * (16 - mystique->dwgreg.beta))) >> 4; + src1[1] = ((src0[1] * mystique->dwgreg.beta) + (src1[1] * (16 - mystique->dwgreg.beta))) >> 4; + src1[2] = ((src0[2] * mystique->dwgreg.beta) + (src1[2] * (16 - mystique->dwgreg.beta))) >> 4; + src1[3] = ((src0[3] * mystique->dwgreg.beta) + (src1[3] * (16 - mystique->dwgreg.beta))) >> 4; + blit_iload_iload_high(mystique, data, 32); + break; + + default: + fatal("blit_iload_iload_highv bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } +} + + +static void +blit_iload_write(mystique_t *mystique, uint32_t data, int size) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { + case DWGCTRL_OPCODE_ILOAD: + blit_iload_iload(mystique, data, size); + break; + + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_iload_scale(mystique, data, size); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_iload_high(mystique, data, size); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_iload_highv(mystique, data, size); + break; + + default: + fatal("blit_iload_write: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); + } +} + + +static int +z_check(uint16_t z, uint16_t old_z, uint32_t z_mode)//mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +{ + switch (z_mode) { + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); + + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; + } +} + + +static void +blit_line(mystique_t *mystique, int closed) +{ + svga_t *svga = &mystique->svga; + uint32_t src, dst, old_dst; + int x; + int z_write; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_RPL: + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = mystique->dwgreg.fcol; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + src = mystique->dwgreg.fcol; + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + src = mystique->dwgreg.fcol; + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + src = mystique->dwgreg.fcol; + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("LINE RSTR/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + + if ((int32_t)mystique->dwgreg.ar[1] >= 0) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + + mystique->dwgreg.length--; + } + break; + + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t old_z = z_p[x]; + + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + int r = 0, g = 0, b = 0; + + if (z_write) + z_p[x] = z; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 17) & 0x3f; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 18) & 0x1f; + dst = (r << 11) | (g << 5) | b; + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + default: + fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + } + + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + + if ((int32_t)mystique->dwgreg.ar[1] >= 0) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + + mystique->dwgreg.length--; + } + break; + + default: + /* pclog("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ + break; + } + + mystique->blitter_complete_refcount++; +} + + +static void +blit_autoline(mystique_t *mystique, int closed) +{ + int start_x = (int32_t)mystique->dwgreg.ar[5]; + int start_y = (int32_t)mystique->dwgreg.ar[6]; + int end_x = (int32_t)mystique->dwgreg.ar[0]; + int end_y = (int32_t)mystique->dwgreg.ar[2]; + int dx = end_x - start_x; + int dy = end_y - start_y; + + if (ABS(dx) > ABS(dy)) { + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.ar[0] = 2*ABS(dy); + mystique->dwgreg.ar[1] = 2*ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2*ABS(dy) - 2*ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); + } else { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.ar[0] = 2*ABS(dx); + mystique->dwgreg.ar[1] = 2*ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2*ABS(dx) - 2*ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); + } + mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; + + blit_line(mystique, closed); + + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; +} + + +static void +blit_trap(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + uint32_t z_back, r_back, g_back, b_back; + int z_write; + int y; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + + mystique->trap_count++; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_BLK: + case DWGCTRL_ATYPE_RPL: + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = + (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = + (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; + *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = + ((pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff) | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = + pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + x_l++; + mystique->pixel_count++; + } + + if ((int32_t)mystique->dwgreg.ar[1] < 0) { + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if ((int32_t)mystique->dwgreg.ar[4] < 0) { + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + case DWGCTRL_ATYPE_RSTR: + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + x_l++; + mystique->pixel_count++; + } + + if ((int32_t)mystique->dwgreg.ar[1] < 0) { + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if ((int32_t)mystique->dwgreg.ar[4] < 0) { + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; + int dx; + + z_back = mystique->dwgreg.dr[0]; + r_back = mystique->dwgreg.dr[4]; + g_back = mystique->dwgreg.dr[8]; + b_back = mystique->dwgreg.dr[12]; + + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + uint32_t dst = 0, old_dst; + int r = 0, g = 0, b = 0; + + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + + if (z_write) + z_p[x_l] = z; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = dither(mystique, r, g, b, x_l & 1, mystique->dwgreg.selline & 1); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; + *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = old_dst | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = b | (g << 8) | (r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + } + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + + x_l++; + mystique->pixel_count++; + } + + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx*mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx*mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx*mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx*mystique->dwgreg.dr[14]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + default: + fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + + mystique->blitter_complete_refcount++; +} + + +static int texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) +{ + svga_t *svga = &mystique->svga; + + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s, t; + + if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + + s = (int32_t)mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t)mystique->dwgreg.tmr[7] >> t_shift; + } else { + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? ((0x100000000ll / (int64_t)(int32_t)mystique->dwgreg.tmr[8]) /*>> 16*/) : 0; + + s = (((int64_t)(int32_t)mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift;/*((16+20)-12);*/ + t = (((int64_t)(int32_t)mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift;/*((16+20)-9);*/ + } + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; + } else + s &= w_mask; + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; + } else + t &= h_mask; + + switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { + case TEXCTL_TEXFORMAT_TW4: + src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + if (s & 1) + src >>= 4; + else + src &= 0xf; + *tex_r = mystique->lut[src | palsel].r; + *tex_g = mystique->lut[src | palsel].g; + *tex_b = mystique->lut[src | palsel].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW8: + src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + *tex_r = mystique->lut[src].r; + *tex_g = mystique->lut[src].g; + *tex_b = mystique->lut[src].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW15: + src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 10) & 0x1f) << 3; + *tex_g = ((src >> 5) & 0x1f) << 3; + *tex_b = (src & 0x1f) << 3; + if (((src >> 15) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key) + *atransp = 1; + else + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW16: + src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = (src >> 11) << 3; + *tex_g = ((src >> 5) & 0x3f) << 2; + *tex_b = (src & 0x1f) << 3; + *atransp = 0; + break; + default: + fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); + break; + } + + return ((src & tkmask) == tckey); +} + + +static void +blit_texture_trap(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + int y; + int z_write; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); + + mystique->trap_count++; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; + int dx; + + uint32_t z_back = mystique->dwgreg.dr[0]; + uint32_t r_back = mystique->dwgreg.dr[4]; + uint32_t g_back = mystique->dwgreg.dr[8]; + uint32_t b_back = mystique->dwgreg.dr[12]; + uint32_t s_back = mystique->dwgreg.tmr[6]; + uint32_t t_back = mystique->dwgreg.tmr[7]; + uint32_t q_back = mystique->dwgreg.tmr[8]; + + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + int tex_r = 0, tex_g = 0, tex_b = 0; + int ctransp, atransp = 0; + int i_r = 0, i_g = 0, i_b = 0; + + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + i_g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + + switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { + case 0: + if (ctransp) + goto skip_pixel; + if (atransp) { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; + + case TEXCTL_DECALCKEY: + if (ctransp) { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; + + case (TEXCTL_STRANS | TEXCTL_DECALCKEY): + if (ctransp) + goto skip_pixel; + break; + + case TEXCTL_TMODULATE: + if (ctransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; + + case (TEXCTL_TMODULATE | TEXCTL_STRANS): + if (ctransp || atransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; + + default: + fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); + } + + if (dest32) { + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + } else { + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + } + if (z_write) + z_p[x_l] = z; + } + } +skip_pixel: + x_l++; + mystique->pixel_count++; + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + } + + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx*mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx*mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx*mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx*mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += dx*mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += dx*mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += dx*mystique->dwgreg.tmr[4]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + default: + fatal("Unknown atype %03x %08x TEXTURE_TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + + mystique->blitter_complete_refcount++; +} + + +static void +blit_bitblt(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + uint32_t src_addr; + int y; + int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; + int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BMONOLEF: + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + int16_t x = x_start; + + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; + uint32_t old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = mystique->dwgreg.fcol; + } else + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = + (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = mystique->dwgreg.fcol; + } else + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = + (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = + (old_dst & 0xff000000) | (mystique->dwgreg.fcol & 0xffffff); + } else + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = + (old_dst & 0xff000000) | (((svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = mystique->dwgreg.fcol; + } else + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = + (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 11] = changeframecount; + break; + + default: + fatal("BITBLT DWGCTRL_ATYPE_BLK unknown MACCESS %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) + x += x_dir; + else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; + + default: + fatal("BITBLT BLK %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + break; + + case DWGCTRL_ATYPE_RPL: + if (mystique->maccess_running & MACCESS_TLUTLOAD) { + src_addr = mystique->dwgreg.ar[3]; + + y = mystique->dwgreg.ydst; + + while (mystique->dwgreg.length) { + uint16_t src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + + mystique->lut[y & 0xff].r = (src >> 11) << 3; + mystique->lut[y & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[y & 0xff].b = (src & 0x1f) << 3; + src_addr++; + y++; + mystique->dwgreg.length--; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BMONOLEF: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; + + while (1) { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; + + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK + + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + default: + fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) + x += x_dir; + else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; + + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BU32RGB: + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t old_src_addr = src_addr; + int16_t x = x_start; + + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x & 3]) { + uint32_t src, dst, old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = svga->vram[src_addr & mystique->vram_mask]; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + src_addr = ((src_addr + x_dir) & 7) | (src_addr & ~7); + else if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; + + if (x != x_end) + x += x_dir; + else + break; + } + + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) { + src_addr = old_src_addr; + if (mystique->dwgreg.sgn.sdy) + src_addr = ((src_addr - 32) & 0xe0) | (src_addr & ~0xe0); + else + src_addr = ((src_addr + 32) & 0xe0) | (src_addr & ~0xe0); + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; + + default: + fatal("BITBLT DWGCTRL_ATYPE_RPL unknown BLTMOD %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + } + break; + + default: + /* pclog("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ + break; + } + + mystique->blitter_complete_refcount++; +} + + +static void +blit_iload(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + /* pclog("ILOAD BLTMOD DWGCTRL = %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); */ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BMONOWF: + case DWGCTRL_BLTMOD_BU24RGB: + case DWGCTRL_BLTMOD_BU32RGB: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + /* pclog("ILOAD busy\n"); */ + mystique->dwgreg.words = 0; + break; + + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + + +static void +blit_idump(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + mystique->dwgreg.words = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.idump_end_of_line = 0; + mystique->busy = 1; + /* pclog("IDUMP ATYPE RPL busy\n"); */ + break; + + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + + +static void +blit_iload_scale(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + /* pclog("ILOAD SCALE ATYPE RPL BLTMOD BUYUV busy\n"); */ + break; + + default: + fatal("ILOAD_SCALE DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD_SCALE atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + + +static void +blit_iload_high(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + /* pclog("ILOAD HIGH ATYPE RPL BLTMOD BUYUV busy\n"); */ + break; + + default: + fatal("ILOAD_HIGH DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD_HIGH atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + + +static +void blit_iload_highv(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + mystique->dwgreg.highv_line = 0; + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; + /* pclog("ILOAD HIGHV ATYPE RPL BLTMOD BUYUV busy\n"); */ + break; + + default: + fatal("ILOAD_HIGHV DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD_HIGHV atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + + +static void +mystique_start_blit(mystique_t *mystique) +{ + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + + mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; + mystique->maccess_running = mystique->maccess; + + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) { + int x, y; + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[y][x] = 1; + } + mystique->dwgreg.src[0] = 0xffffffff; + mystique->dwgreg.src[1] = 0xffffffff; + mystique->dwgreg.src[2] = 0xffffffff; + mystique->dwgreg.src[3] = 0xffffffff; + } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_ARZERO) { + mystique->dwgreg.ar[0] = 0; + mystique->dwgreg.ar[1] = 0; + mystique->dwgreg.ar[2] = 0; + mystique->dwgreg.ar[4] = 0; + mystique->dwgreg.ar[5] = 0; + mystique->dwgreg.ar[6] = 0; + } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SGNZERO) { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.sgn.scanleft = 0; + mystique->dwgreg.sgn.sdxl = 0; + mystique->dwgreg.sgn.sdy = 0; + mystique->dwgreg.sgn.sdxr = 0; + } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SHTZERO) { + mystique->dwgreg.funcnt = 0; + mystique->dwgreg.stylelen = 0; + mystique->dwgreg.xoff = 0; + mystique->dwgreg.yoff = 0; + } + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { + case DWGCTRL_OPCODE_LINE_OPEN: + blit_line(mystique, 0); + break; + + case DWGCTRL_OPCODE_AUTOLINE_OPEN: + blit_autoline(mystique, 0); + break; + + case DWGCTRL_OPCODE_AUTOLINE_CLOSE: + blit_autoline(mystique, 1); + break; + + case DWGCTRL_OPCODE_TRAP: + blit_trap(mystique); + break; + + case DWGCTRL_OPCODE_TEXTURE_TRAP: + blit_texture_trap(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_high(mystique); + break; + + case DWGCTRL_OPCODE_BITBLT: + blit_bitblt(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD: + blit_iload(mystique); + break; + + case DWGCTRL_OPCODE_IDUMP: + blit_idump(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_scale(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_highv(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_FILTER: + /* TODO: Actually implement this. */ + break; + + default: + fatal("mystique_start_blit: unknown blit %08x\n", mystique->dwgreg.dwgctrl_running); + } + + end_time = plat_timer_read(); + mystique->blitter_time += end_time - start_time; +} + + +static void +mystique_hwcursor_draw(svga_t *svga, int displine) +{ + int x; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + + dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += 16; + for (x = 0; x < 64; x ++) { + if (!(dat[1] & (1ull << 63))) + buffer32->line[displine][offset + svga->x_add] = (dat[0] & (1ull << 63)) ? 0xffffff : 0; + else if (dat[0] & (1ull << 63)) + buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + + +static +uint8_t mystique_pci_read(int func, int addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + uint8_t ret = 0x00; + + if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) + ret = 0x00; + else switch (addr) { + case 0x00: ret = 0x2b; break; /*Matrox*/ + case 0x01: ret = 0x10; break; + + case 0x02: ret = 0x1a; break; /*MGA-1064SG*/ + case 0x03: ret = 0x05; break; + + case PCI_REG_COMMAND: + ret = mystique->pci_regs[PCI_REG_COMMAND]; break; /*Respond to IO and memory accesses*/ + + case 0x07: ret = 0 << 1; break; /*Fast DEVSEL timing*/ + + case 0x08: ret = 0; break; /*Revision ID*/ + case 0x09: ret = 0; break; /*Programming interface*/ + + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ + case 0x0b: ret = 0x03; break; + + case 0x10: ret = 0x00; break; /*Control aperture*/ + case 0x11: ret = (mystique->ctrl_base >> 8) & 0xc0; break; + case 0x12: ret = mystique->ctrl_base >> 16; break; + case 0x13: ret = mystique->ctrl_base >> 24; break; + + case 0x14: ret = 0x00; break; /*Linear frame buffer*/ + case 0x16: ret = (mystique->lfb_base >> 16) & 0x80; break; + case 0x17: ret = mystique->lfb_base >> 24; break; + + case 0x18: ret = 0x00; break; /*Pseudo-DMA (ILOAD)*/ + case 0x1a: ret = (mystique->iload_base >> 16) & 0x80; break; + case 0x1b: ret = mystique->iload_base >> 24; break; + + case 0x30: ret = mystique->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ + case 0x31: ret = 0x00; break; + case 0x32: ret = mystique->pci_regs[0x32]; break; + case 0x33: ret = mystique->pci_regs[0x33]; break; + + case 0x3c: ret = mystique->int_line; break; + case 0x3d: ret = PCI_INTA; break; + + case 0x40: ret = mystique->pci_regs[0x40]; break; + case 0x41: ret = mystique->pci_regs[0x41]; break; + case 0x42: ret = mystique->pci_regs[0x42]; break; + case 0x43: ret = mystique->pci_regs[0x43]; break; + + case 0x44: ret = mystique->pci_regs[0x44]; break; + case 0x45: ret = mystique->pci_regs[0x45]; break; + + case 0x48: case 0x49: case 0x4a: case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | + (addr & 3); + ret = mystique_ctrl_read_b(addr, mystique); break; + } + + return ret; +} + +static void +mystique_pci_write(int func, int addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + switch (addr) { + case PCI_REG_COMMAND: + mystique->pci_regs[PCI_REG_COMMAND] = val & 0x23; + mystique_recalc_mapping(mystique); + break; + + case 0x11: + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + break; + case 0x12: + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + break; + case 0x13: + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + break; + + case 0x16: + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x17: + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; + + case 0x1a: + mystique->iload_base = (mystique->iload_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x1b: + mystique->iload_base = (mystique->iload_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; + + case 0x30: case 0x32: case 0x33: + if (!(mystique->pci_regs[0x43] & 0x40)) + return; + mystique->pci_regs[addr] = val; + if (mystique->pci_regs[0x30] & 0x01) { + uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&mystique->bios_rom.mapping); + return; + + case 0x3c: + mystique->int_line = val; + return; + + case 0x40: case 0x41: case 0x42: case 0x43: + mystique->pci_regs[addr] = val; + if (addr == 0x43) { + if (val & 0x40) { + if (mystique->pci_regs[0x30] & 0x01) { + uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&mystique->bios_rom.mapping); + } else + mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, 0x8000); + } + break; + + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + mystique->pci_regs[addr-0x20] = val; + break; + + case 0x44: case 0x45: + mystique->pci_regs[addr] = val; + break; + + case 0x48: case 0x49: case 0x4a: case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | + (addr & 3); + mystique_ctrl_write_b(addr, val, mystique); + break; + } +} + + + +static void * +mystique_init(const device_t *info) +{ + int c; + mystique_t *mystique = malloc(sizeof(mystique_t)); + wchar_t *romfn; + + memset(mystique, 0, sizeof(mystique_t)); + + if (info->local == 1) + romfn = ROM_MYSTIQUE_220; + else + romfn = ROM_MYSTIQUE; + + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&mystique->bios_rom.mapping); + + mystique->vram_size = device_get_config_int("memory"); + mystique->vram_mask = (mystique->vram_size << 20) - 1; + mystique->vram_mask_w = mystique->vram_mask >> 1; + mystique->vram_mask_l = mystique->vram_mask >> 2; + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); + + svga_init(&mystique->svga, mystique, mystique->vram_size << 20, + mystique_recalctimings, + mystique_in, mystique_out, + mystique_hwcursor_draw, + NULL); + + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + mem_mapping_add(&mystique->ctrl_mapping, 0, 0, + mystique_ctrl_read_b, NULL, mystique_ctrl_read_l, + mystique_ctrl_write_b, NULL, mystique_ctrl_write_l, + NULL, 0, mystique); + mem_mapping_disable(&mystique->ctrl_mapping); + + mem_mapping_add(&mystique->lfb_mapping, 0, 0, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, 0, mystique); + mem_mapping_disable(&mystique->lfb_mapping); + + mem_mapping_add(&mystique->iload_mapping, 0, 0, + mystique_iload_read_b, NULL, mystique_iload_read_l, + mystique_iload_write_b, NULL, mystique_iload_write_l, + NULL, 0, mystique); + mem_mapping_disable(&mystique->iload_mapping); + + mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); + mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ff8]; + + mystique->svga.miscout = 1; + mystique->pci_regs[0x41] = 0x01; /* vgaboot = 1 */ + mystique->pci_regs[0x43] = 0x40; /* biosen = 1 */ + + for (c = 0; c < 256; c++) { + dither5[c][0][0] = c >> 3; + dither5[c][1][1] = (c + 2) >> 3; + dither5[c][1][0] = (c + 4) >> 3; + dither5[c][0][1] = (c + 6) >> 3; + + if (dither5[c][1][1] > 31) + dither5[c][1][1] = 31; + if (dither5[c][1][0] > 31) + dither5[c][1][0] = 31; + if (dither5[c][0][1] > 31) + dither5[c][0][1] = 31; + + dither6[c][0][0] = c >> 2; + dither6[c][1][1] = (c + 1) >> 2; + dither6[c][1][0] = (c + 2) >> 2; + dither6[c][0][1] = (c + 3) >> 2; + + if (dither6[c][1][1] > 63) + dither6[c][1][1] = 63; + if (dither6[c][1][0] > 63) + dither6[c][1][0] = 63; + if (dither6[c][0][1] > 63) + dither6[c][0][1] = 63; + } + + mystique->wake_fifo_thread = thread_create_event(); + mystique->fifo_not_full_event = thread_create_event(); + mystique->fifo_thread = thread_create(fifo_thread, mystique); + mystique->dma.lock = thread_create_mutex(L"86Box.MGAMutex"); + + timer_add(&mystique->wake_timer, mystique_wake_timer, (void *)mystique, 0); + timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *)mystique, 1); + + mystique->status = STATUS_ENDPRDMASTS; + + return mystique; +} + + +static void +mystique_close(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + thread_kill(mystique->fifo_thread); + thread_destroy_event(mystique->wake_fifo_thread); + thread_destroy_event(mystique->fifo_not_full_event); + thread_close_mutex(mystique->dma.lock); + + svga_close(&mystique->svga); + + free(mystique); +} + + +static int +mystique_available(void) +{ + return rom_present(ROM_MYSTIQUE); +} + + +static int +mystique_220_available(void) +{ + return rom_present(ROM_MYSTIQUE_220); +} + + +static void +mystique_speed_changed(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + svga_recalctimings(&mystique->svga); +} + + +static void +mystique_force_redraw(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + mystique->svga.fullchange = changeframecount; +} + + +static const device_config_t mystique_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "" + } + }, + .default_int = 8 + }, + { + .type = -1 + } +}; + + +const device_t mystique_device = +{ + "Matrox Mystique", + DEVICE_PCI, + 0, + mystique_init, + mystique_close, + NULL, + mystique_available, + mystique_speed_changed, + mystique_force_redraw, + mystique_config +}; + + +const device_t mystique_220_device = +{ + "Matrox Mystique 220", + DEVICE_PCI, + 1, + mystique_init, + mystique_close, + NULL, + mystique_220_available, + mystique_speed_changed, + mystique_force_redraw, + mystique_config +}; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 9135450b2..332dfb09a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -18,16 +18,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "plat.h" #include "video.h" -#include "vid_mga.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -269,6 +268,7 @@ #define DWGCTRL_BLTMOD_MASK (0xf << 25) #define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) #define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) +#define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25) #define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) #define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) #define DWGCTRL_BLTMOD_BUYUV (0xe << 25) @@ -1551,6 +1551,9 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) break; case REG_OPMODE: + thread_wait_mutex(mystique->dma.lock); + mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ + thread_release_mutex(mystique->dma.lock); mystique->dmamod = (val >> 2) & 3; mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); break; @@ -1958,6 +1961,7 @@ mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); } + static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) { @@ -1995,7 +1999,9 @@ mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) } } -static uint8_t mystique_readb_linear(uint32_t addr, void *p) + +static uint8_t +mystique_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -2009,7 +2015,10 @@ static uint8_t mystique_readb_linear(uint32_t addr, void *p) return svga->vram[addr & svga->vram_mask]; } -static uint16_t mystique_readw_linear(uint32_t addr, void *p) + + +static uint16_t +mystique_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -2023,7 +2032,10 @@ static uint16_t mystique_readw_linear(uint32_t addr, void *p) return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } -static uint32_t mystique_readl_linear(uint32_t addr, void *p) + + +static uint32_t +mystique_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -2038,7 +2050,9 @@ static uint32_t mystique_readl_linear(uint32_t addr, void *p) return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } -static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) + +static void +mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -2053,7 +2067,10 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) svga->changedvram[addr >> 12] = changeframecount; svga->vram[addr] = val; } -static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) + + +static void +mystique_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -2068,7 +2085,10 @@ static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *)&svga->vram[addr] = val; } -static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) + + +static void +mystique_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *)p; @@ -2580,6 +2600,7 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { svga_t *svga = &mystique->svga; uint32_t src, dst; + uint32_t dst2; uint64_t data64; int min_size = 8; uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; @@ -2877,6 +2898,45 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) mystique->dwgreg.iload_rem_count = size; break; + case DWGCTRL_BLTMOD_BU32BGR: + size += mystique->dwgreg.iload_rem_count; + while (size >= 32) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst2 = ((dst >> 16) & 0xff) | (dst & 0xff00) | ((dst & 0xff) << 16); /* BGR to RGB */ + + dst = bitop(data, dst2, mystique->dwgreg.dwgctrl_running); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BU32RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + size = 0; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + + mystique->dwgreg.iload_rem_count = size; + break; + default: fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); break; @@ -3063,6 +3123,21 @@ blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) size = 32; break; + case DWGCTRL_BLTMOD_BU32BGR: + r = ((data >> 16) & 0xff); + CLAMP(r); + g = ((data >> 8) & 0xff); + CLAMP(g); + b = (data & 0xff); + CLAMP(b); + + next_r = r; + next_g = g; + next_b = b; + + size = 32; + break; + default: fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); break; @@ -4332,6 +4407,7 @@ blit_iload_high(mystique_t *mystique) case DWGCTRL_ATYPE_RPL: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BUYUV: + case DWGCTRL_BLTMOD_BU32BGR: mystique->dwgreg.length_cur = mystique->dwgreg.length; mystique->dwgreg.xdst = mystique->dwgreg.fxleft; mystique->dwgreg.iload_rem_data = 0; @@ -4531,9 +4607,12 @@ uint8_t mystique_pci_read(int func, int addr, void *p) case 0x03: ret = 0x05; break; case PCI_REG_COMMAND: - ret = mystique->pci_regs[PCI_REG_COMMAND]; break; /*Respond to IO and memory accesses*/ + ret = mystique->pci_regs[PCI_REG_COMMAND] | 0x80; break; /*Respond to IO and memory accesses*/ + case 0x05: + ret = 0x00; break; - case 0x07: ret = 0 << 1; break; /*Fast DEVSEL timing*/ + case 0x06: ret = 0x80; break; + case 0x07: ret = mystique->pci_regs[0x07]; break; /*Fast DEVSEL timing*/ case 0x08: ret = 0; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ @@ -4554,6 +4633,11 @@ uint8_t mystique_pci_read(int func, int addr, void *p) case 0x1a: ret = (mystique->iload_base >> 16) & 0x80; break; case 0x1b: ret = mystique->iload_base >> 24; break; + case 0x2c: ret = mystique->pci_regs[0x2c]; break; + case 0x2d: ret = mystique->pci_regs[0x2d]; break; + case 0x2e: ret = mystique->pci_regs[0x2e]; break; + case 0x2f: ret = mystique->pci_regs[0x2f]; break; + case 0x30: ret = mystique->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: ret = mystique->pci_regs[0x32]; break; @@ -4586,10 +4670,18 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { case PCI_REG_COMMAND: - mystique->pci_regs[PCI_REG_COMMAND] = val & 0x23; + mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; mystique_recalc_mapping(mystique); break; + case 0x07: + mystique->pci_regs[0x07] &= ~(val & 0x38); + break; + + case 0x0d: + mystique->pci_regs[0x0d] = val; + break; + case 0x11: mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); mystique_recalc_mapping(mystique); @@ -4636,7 +4728,16 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) mystique->int_line = val; return; - case 0x40: case 0x41: case 0x42: case 0x43: + case 0x40: + mystique->pci_regs[addr] = val & 0x3f; + break; + case 0x41: + mystique->pci_regs[addr] = val; + break; + case 0x42: + mystique->pci_regs[addr] = val & 0x1f; + break; + case 0x43: mystique->pci_regs[addr] = val; if (addr == 0x43) { if (val & 0x40) { @@ -4651,16 +4752,20 @@ mystique_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: - mystique->pci_regs[addr-0x20] = val; + mystique->pci_regs[addr - 0x20] = val; break; - case 0x44: case 0x45: - mystique->pci_regs[addr] = val; + case 0x44: + mystique->pci_regs[addr] = val & 0xfc; + break; + case 0x45: + mystique->pci_regs[addr] = val & 0x3f; break; case 0x48: case 0x49: case 0x4a: case 0x4b: addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); + pclog("mystique_ctrl_write_b(%04X, %02X)\n", addr, val); mystique_ctrl_write_b(addr, val, mystique); break; } @@ -4718,10 +4823,12 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->iload_mapping); mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); + mystique->pci_regs[0x06] = 0x80; + mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff9]; + mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ffa]; + mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ffb]; mystique->svga.miscout = 1; mystique->pci_regs[0x41] = 0x01; /* vgaboot = 1 */ diff --git a/src/video/vid_mga.h b/src/video/vid_mga.h deleted file mode 100644 index 5291c81e4..000000000 --- a/src/video/vid_mga.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Matrox MGA graphics card emulation. - * - * Version: @(#)vid_mga.h 1.0.1 2020/01/18 - * - * Author: Sarah Walker, - * Copyright 2008-2020 Sarah Walker. - */ - -extern const device_t mystique_device; -extern const device_t mystique_220_device; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 2addd8b32..09e56cb10 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -20,14 +20,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_oak_oti.h" #include "vid_svga.h" #define BIOS_037C_PATH L"roms/video/oti/bios.bin" diff --git a/src/video/vid_oak_oti.h b/src/video/vid_oak_oti.h deleted file mode 100644 index e59d6bcc7..000000000 --- a/src/video/vid_oak_oti.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t oti037c_device; -extern const device_t oti067_device; -extern const device_t oti067_acer386_device; -extern const device_t oti067_ama932j_device; -extern const device_t oti077_device; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 5333980de..ad05e824b 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -23,14 +23,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_paradise.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_paradise.h b/src/video/vid_paradise.h deleted file mode 100644 index bdc4734aa..000000000 --- a/src/video/vid_paradise.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -extern const device_t paradise_pvga1a_pc2086_device; -extern const device_t paradise_pvga1a_pc3086_device; -extern const device_t paradise_pvga1a_device; -extern const device_t paradise_wd90c11_megapc_device; -extern const device_t paradise_wd90c11_device; -extern const device_t paradise_wd90c30_device; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 0dbaa9595..3db6b4521 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -79,14 +79,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../pit.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "pit.h" +#include "plat.h" #include "video.h" #include "vid_cga.h" #include "vid_pgc.h" diff --git a/src/video/vid_pgc.h b/src/video/vid_pgc.h index 82ef899ea..d1e8c4ffa 100644 --- a/src/video/vid_pgc.h +++ b/src/video/vid_pgc.h @@ -181,7 +181,4 @@ extern void pgc_hndl_lut8(pgc_t *); extern void pgc_hndl_lut8rd(pgc_t *); -extern const device_t pgc_device; - - #endif /*VID_PGC_H*/ diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index f12239725..60d3a5f4b 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -21,24 +21,18 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "plat.h" #include "video.h" -#include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_sdac_ramdac.h" -#include "vid_att20c49x_ramdac.h" -#include "vid_bt48x_ramdac.h" -#include "vid_av9194.h" -#include "vid_icd2061.h" -#include "../cpu/cpu.h" +#include "cpu.h" #define ROM_ORCHID_86C911 L"roms/video/s3/BIOS.BIN" #define ROM_METHEUS_86C928 L"roms/video/s3/928.vbi" @@ -1595,7 +1589,6 @@ uint8_t s3_in(uint16_t addr, void *p) void s3_recalctimings(svga_t *svga) { s3_t *s3 = (s3_t *)svga->p; - bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; int clk_sel = (svga->miscout >> 2) & 3; svga->hdisp = svga->hdisp_old; @@ -1616,11 +1609,9 @@ void s3_recalctimings(svga_t *svga) else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; - if (s3->chip == S3_VISION964 || s3->chip == S3_86C928) { - svga->interlace = ramdac->cmd_r2 & 0x08; - if (ramdac->cmd_r3 & 0x08) - svga->hdisp *= 2; /* x2 clock multiplier */ - } else + if (s3->chip == S3_VISION964 || s3->chip == S3_86C928) + bt48x_recalctimings(svga->ramdac, svga); + else svga->interlace = svga->crtc[0x42] & 0x20; if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64)) @@ -3769,6 +3760,9 @@ static const device_config_t s3_config[] = { "4 MB", 4 }, + { + "8 MB", 8 + }, { "" } @@ -4034,7 +4028,7 @@ const device_t s3_phoenix_vision864_pci_device = const device_t s3_diamond_stealth64_vlb_device = { "S3 Trio64 (Diamond Stealth64 DRAM) VLB", - DEVICE_VLB, + DEVICE_PCI, S3_DIAMOND_STEALTH64_764, s3_init, s3_close, diff --git a/src/video/vid_s3.h b/src/video/vid_s3.h deleted file mode 100644 index a44d5cc27..000000000 --- a/src/video/vid_s3.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 - * graphics cards. - * - * Version: @(#)vid_s3.h 1.0.4 2019/01/12 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ - -const device_t s3_orchid_86c911_isa_device; -const device_t s3_metheus_premier_86c928_isa_device; -const device_t s3_metheus_premier_86c928_vlb_device; -const device_t s3_v7mirage_86c801_isa_device; -const device_t s3_phoenix_86c805_vlb_device; -const device_t s3_bahamas64_vlb_device; -const device_t s3_bahamas64_pci_device; -const device_t s3_9fx_vlb_device; -const device_t s3_9fx_pci_device; -const device_t s3_phoenix_trio32_vlb_device; -const device_t s3_phoenix_trio32_pci_device; -const device_t s3_phoenix_trio64_vlb_device; -const device_t s3_phoenix_trio64_onboard_pci_device; -const device_t s3_phoenix_trio64_pci_device; -const device_t s3_phoenix_vision864_pci_device; -const device_t s3_phoenix_vision864_vlb_device; -const device_t s3_diamond_stealth64_pci_device; -const device_t s3_diamond_stealth64_vlb_device; -const device_t s3_diamond_stealth64_964_pci_device; -const device_t s3_diamond_stealth64_964_vlb_device; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 1e1bf4dad..358c3c749 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -23,16 +23,15 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "plat.h" #include "video.h" -#include "vid_s3_virge.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_s3_virge.h b/src/video/vid_s3_virge.h deleted file mode 100644 index 2d340f649..000000000 --- a/src/video/vid_s3_virge.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t s3_virge_vlb_device; -extern const device_t s3_virge_pci_device; -extern const device_t s3_virge_988_vlb_device; -extern const device_t s3_virge_988_pci_device; -extern const device_t s3_virge_375_vlb_device; -extern const device_t s3_virge_375_pci_device; -extern const device_t s3_virge_375_4_vlb_device; -extern const device_t s3_virge_375_4_pci_device; diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 75cb01995..882f892b0 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -29,12 +29,19 @@ #include "../timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_sc1502x_ramdac.h" + + +typedef struct +{ + int state; + uint8_t ctrl; +} sc1502x_ramdac_t; void -sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; int oldbpp = 0; switch (addr) { @@ -102,10 +109,10 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t uint8_t -sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) { - uint8_t temp; - temp = svga_in(addr, svga); + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; + uint8_t temp = svga_in(addr, svga); switch (addr) { case 0x3C6: diff --git a/src/video/vid_sc1502x_ramdac.h b/src/video/vid_sc1502x_ramdac.h deleted file mode 100644 index a5dcd234c..000000000 --- a/src/video/vid_sc1502x_ramdac.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Header of the emulation of a Sierra SC1502X RAMDAC. - * - * Used by the TLIVESA1 driver for ET4000. - * - * Version: @(#)vid_sc1502x_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct -{ - int state; - uint8_t ctrl; -} sc1502x_ramdac_t; - -extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga); -extern uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga); - -extern const device_t sc1502x_ramdac_device; diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 44fb8d752..498daf432 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -21,13 +21,22 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "device.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_sdac_ramdac.h" + + +typedef struct sdac_ramdac_t +{ + uint16_t regs[256]; + int magic_count, + windex, rindex, + reg_ff, rs2; + uint8_t type, command; +} sdac_ramdac_t; static void @@ -96,8 +105,9 @@ sdac_reg_read(sdac_ramdac_t *ramdac, int reg) void -sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) +sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; uint8_t rs = (addr & 0x03); rs |= (!!rs2 << 8); @@ -132,8 +142,9 @@ sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga uint8_t -sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga) +sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); rs |= (!!rs2 << 8); diff --git a/src/video/vid_sdac_ramdac.h b/src/video/vid_sdac_ramdac.h deleted file mode 100644 index e57d24519..000000000 --- a/src/video/vid_sdac_ramdac.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * 87C716 'SDAC' true colour RAMDAC emulation header. - * - * Version: @(#)vid_sdac_ramdac.h 1.0.1 2019/09/13 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - */ -typedef struct sdac_ramdac_t -{ - uint16_t regs[256]; - int magic_count, - windex, rindex, - reg_ff, rs2; - uint8_t type, command; -} sdac_ramdac_t; - -extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); -extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga); -extern float sdac_getclock(int clock, void *p); - -extern const device_t gendac_ramdac_device; -extern const device_t sdac_ramdac_device; diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 3ad4a2a54..7193783f1 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -19,17 +19,16 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../nmi.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "nmi.h" +#include "rom.h" +#include "device.h" #include "video.h" -#include "vid_sigma.h" #define ROM_SIGMA_FONT L"roms/video/sigma/sigma400_font.rom" diff --git a/src/video/vid_sigma.h b/src/video/vid_sigma.h deleted file mode 100644 index e331ad753..000000000 --- a/src/video/vid_sigma.h +++ /dev/null @@ -1,2 +0,0 @@ -extern const device_t sigma_device; - diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index 75722ef5a..4900ff5b8 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -27,7 +27,15 @@ #include "../timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_stg_ramdac.h" + + +typedef struct stg_ramdac_t +{ + int magic_count, index; + uint8_t regs[256]; + uint8_t command; +} stg_ramdac_t; + static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; @@ -82,8 +90,9 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) void -stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) +stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + stg_ramdac_t *ramdac = (stg_ramdac_t *) p; int didwrite, old; switch (addr) { @@ -136,8 +145,9 @@ stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) uint8_t -stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) +stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) { + stg_ramdac_t *ramdac = (stg_ramdac_t *) p; uint8_t temp = 0xff; switch (addr) { diff --git a/src/video/vid_stg_ramdac.h b/src/video/vid_stg_ramdac.h deleted file mode 100644 index 76dbfcd3e..000000000 --- a/src/video/vid_stg_ramdac.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * STG1702 true colour RAMDAC emulation header. - * - * Version: @(#)vid_stg_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct stg_ramdac_t -{ - int magic_count, index; - uint8_t regs[256]; - uint8_t command; -} stg_ramdac_t; - -extern void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); -extern uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); -extern float stg_getclock(int clock, void *p); - -extern const device_t stg_ramdac_device; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 5314f33d8..efceec413 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -25,14 +25,14 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../io.h" -#include "../pit.h" -#include "../mem.h" -#include "../rom.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "timer.h" +#include "86box_io.h" +#include "pit.h" +#include "mem.h" +#include "rom.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index d04a1bb99..d2076c2eb 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -109,10 +109,10 @@ typedef struct svga_t void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); float (*getclock)(int clock, void *p); - /*Called when VC=R18 and friends. If this returns zero then MA resetting - is skipped. Matrox Mystique in Power mode reuses this counter for - vertical line interrupt*/ - int (*line_compare)(struct svga_t *svga); + /* Called when VC=R18 and friends. If this returns zero then MA resetting + is skipped. Matrox Mystique in Power mode reuses this counter for + vertical line interrupt*/ + int (*line_compare)(struct svga_t *svga); /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ @@ -131,7 +131,6 @@ typedef struct svga_t dac_mask, dac_status, ksc5601_sbyte_mask; - int vertical_linedbl; /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ @@ -188,3 +187,69 @@ enum { RAMDAC_6BIT = 0, RAMDAC_8BIT }; + + +/* We need a way to add a device with a pointer to a parent device so it can attach itself to it, and + possibly also a second ATi 68860 RAM DAC type that auto-sets SVGA render on RAM DAC render change. */ +extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern void ati68860_set_ramdac_type(void *p, int type); +extern void ati68860_ramdac_set_render(void *p, svga_t *svga); +extern void ati68860_ramdac_set_pallook(void *p, int i, uint32_t col); +extern void ati68860_hwcursor_draw(svga_t *svga, int displine); + +extern void att49x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t att49x_ramdac_in(uint16_t addr, void *p, svga_t *svga); + +extern float av9194_getclock(int clock, void *p); + +extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga); +extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga); +extern void bt48x_recalctimings(void *p, svga_t *svga); +extern void bt48x_hwcursor_draw(svga_t *svga, int displine); + +extern void icd2061_write(void *p, int val); +extern float icd2061_getclock(int clock, void *p); + +/* The code is the same, the #define's are so that the correct name can be used. */ +#define ics9161_write icd2061_write +#define ics9161_getclock icd2061_getclock + +extern void ics2595_write(void *p, int strobe, int dat); +extern double ics2595_getclock(void *p); +extern void ics2595_setclock(void *p, double clock); + +extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga); + +extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); +extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); +extern float sdac_getclock(int clock, void *p); + +extern void stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t stg_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern float stg_getclock(int clock, void *p); + +extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga); + + +#ifdef EMU_DEVICE_H +extern const device_t ati68860_ramdac_device; +extern const device_t att490_ramdac_device; +extern const device_t att492_ramdac_device; +extern const device_t av9194_device; +extern const device_t bt484_ramdac_device; +extern const device_t att20c504_ramdac_device; +extern const device_t bt485_ramdac_device; +extern const device_t att20c505_ramdac_device; +extern const device_t bt485a_ramdac_device; +extern const device_t gendac_ramdac_device; +extern const device_t ics2595_device; +extern const device_t icd2061_device; +extern const device_t ics9161_device; +extern const device_t sc1502x_ramdac_device; +extern const device_t sdac_ramdac_device; +extern const device_t stg_ramdac_device; +extern const device_t tkd8001_ramdac_device; +#endif diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 2448bd1fb..499c02f91 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -20,9 +20,9 @@ #include #include #include -#include "../86box.h" -#include "../mem.h" -#include "../timer.h" +#include "86box.h" +#include "mem.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 5c33070f2..9043242d1 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -23,45 +23,19 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../timer.h" -#include "../machine/machine.h" -#include "../mem.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "timer.h" +#include "machine.h" +#include "mem.h" +#include "device.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" -#include "vid_ati18800.h" -#include "vid_ati28800.h" -#include "vid_ati_mach64.h" #include "vid_cga.h" -#include "vid_cl54xx.h" -#include "vid_compaq_cga.h" #include "vid_ega.h" -#include "vid_et4000.h" -#include "vid_et4000w32.h" -#include "vid_genius.h" -#include "vid_hercules.h" -#include "vid_herculesplus.h" -#include "vid_ht216.h" -#include "vid_im1024.h" -#include "vid_incolor.h" #include "vid_colorplus.h" #include "vid_mda.h" -#include "vid_mga.h" -#include "vid_oak_oti.h" -#include "vid_paradise.h" -#include "vid_pgc.h" -#include "vid_s3.h" -#include "vid_s3_virge.h" -#include "vid_sigma.h" -#include "vid_tgui9440.h" -#include "vid_ti_cf62011.h" -#include "vid_tvga.h" -#include "vid_vga.h" -#include "vid_voodoo.h" -#include "vid_wy700.h" typedef struct { diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index a80ea293f..3290d25cf 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -60,20 +60,18 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../device.h" -#include "../cpu/cpu.h" -#include "../plat.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "device.h" +#include "cpu.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_tkd8001_ramdac.h" -#include "vid_tgui9440.h" /*TGUI9400CXi has extended write modes, controlled by extended GDC registers : diff --git a/src/video/vid_tgui9440.h b/src/video/vid_tgui9440.h deleted file mode 100644 index 24208e913..000000000 --- a/src/video/vid_tgui9440.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t tgui9400cxi_device; -extern const device_t tgui9440_vlb_device; -extern const device_t tgui9440_pci_device; diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index e77ce27c9..dde469ba7 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -57,16 +57,14 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../video/video.h" -#include "../video/vid_vga.h" -#include "../video/vid_svga.h" -#include "vid_ti_cf62011.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "video.h" +#include "vid_svga.h" typedef struct { diff --git a/src/video/vid_ti_cf62011.h b/src/video/vid_ti_cf62011.h deleted file mode 100644 index 185f98511..000000000 --- a/src/video/vid_ti_cf62011.h +++ /dev/null @@ -1,4 +0,0 @@ -#if defined(DEV_BRANCH) && defined(USE_TI) -extern const device_t ti_cf62011_device; -#endif -extern const device_t ibm_ps1_2121_device; diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index e7c381a79..26118f1a4 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -21,18 +21,26 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../timer.h" -#include "../mem.h" +#include "86box.h" +#include "device.h" +#include "timer.h" +#include "mem.h" #include "video.h" #include "vid_svga.h" -#include "vid_tkd8001_ramdac.h" + + +typedef struct tkd8001_ramdac_t +{ + int state; + uint8_t ctrl; +} tkd8001_ramdac_t; void -tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) +tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + switch (addr) { case 0x3C6: if (ramdac->state == 4) { @@ -70,8 +78,10 @@ tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t uint8_t -tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) +tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga) { + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; + switch (addr) { case 0x3C6: if (ramdac->state == 4) diff --git a/src/video/vid_tkd8001_ramdac.h b/src/video/vid_tkd8001_ramdac.h deleted file mode 100644 index 3cfa166b0..000000000 --- a/src/video/vid_tkd8001_ramdac.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Trident TKD8001 RAMDAC emulation header. - * - * Version: @(#)vid_tkd8001_ramdac.h 1.0.0 2018/10/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -typedef struct tkd8001_ramdac_t -{ - int state; - uint8_t ctrl; -} tkd8001_ramdac_t; - -extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); -extern uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); - -extern const device_t tkd8001_ramdac_device; diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 8e2fd3bc3..301e03816 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -21,17 +21,15 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "mem.h" +#include "rom.h" +#include "device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_tkd8001_ramdac.h" -#include "vid_tvga.h" #define TVGA8900B_ID 0x03 #define TVGA8900CLD_ID 0x33 diff --git a/src/video/vid_tvga.h b/src/video/vid_tvga.h deleted file mode 100644 index 6a4f0105a..000000000 --- a/src/video/vid_tvga.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t tvga8900b_device; -extern const device_t tvga8900d_device; diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index b01e9fa53..e38afa6d7 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -21,15 +21,14 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" +#include "86box.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" #include "video.h" #include "vid_svga.h" -#include "vid_vga.h" typedef struct vga_t diff --git a/src/video/vid_vga.h b/src/video/vid_vga.h deleted file mode 100644 index 533fdbb9a..000000000 --- a/src/video/vid_vga.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern const device_t vga_device; -extern const device_t ps1vga_device; -extern const device_t ps1vga_mca_device; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 8e16ac236..e3c0d91a6 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -22,19 +22,18 @@ #include #include #include -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../machine/machine.h" -#include "../device.h" -#include "../mem.h" -#include "../pci.h" -#include "../rom.h" -#include "../timer.h" -#include "../device.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "device.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "timer.h" +#include "device.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" -#include "vid_voodoo.h" #include "vid_voodoo_dither.h" #ifdef CLAMP diff --git a/src/video/vid_voodoo.h b/src/video/vid_voodoo.h deleted file mode 100644 index 9752899f7..000000000 --- a/src/video/vid_voodoo.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t voodoo_device; diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index b490dc4a6..00fb1b822 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -21,14 +21,13 @@ #include #include #include -#include "../86box.h" -#include "../io.h" -#include "../timer.h" -#include "../pit.h" -#include "../mem.h" -#include "../device.h" +#include "86box.h" +#include "86box_io.h" +#include "timer.h" +#include "pit.h" +#include "mem.h" +#include "device.h" #include "video.h" -#include "vid_wy700.h" #define WY700_XSIZE 1280 diff --git a/src/video/vid_wy700.h b/src/video/vid_wy700.h deleted file mode 100644 index 0c8a986fe..000000000 --- a/src/video/vid_wy700.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t wy700_device; diff --git a/src/video/video.c b/src/video/video.c index e7504f4b5..0c4672086 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -58,14 +58,14 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../cpu/cpu.h" -#include "../io.h" -#include "../mem.h" -#include "../rom.h" -#include "../config.h" -#include "../timer.h" -#include "../plat.h" +#include "86box.h" +#include "cpu.h" +#include "86box_io.h" +#include "mem.h" +#include "rom.h" +#include "config.h" +#include "timer.h" +#include "plat.h" #include "video.h" #include "vid_svga.h" diff --git a/src/video/video.h b/src/video/video.h index a82993cfd..b27e29862 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -190,4 +190,164 @@ extern uint32_t video_color_transform(uint32_t color); #endif +#ifdef EMU_DEVICE_H +/* ATi Mach64 */ +extern const device_t mach64gx_isa_device; +extern const device_t mach64gx_vlb_device; +extern const device_t mach64gx_pci_device; +extern const device_t mach64vt2_device; + +/* ATi 18800 */ +extern const device_t ati18800_wonder_device; +extern const device_t ati18800_vga88_device; +extern const device_t ati18800_device; + +/* ATi 28800 */ +extern const device_t ati28800_device; +extern const device_t ati28800k_device; +extern const device_t compaq_ati28800_device; +#if defined(DEV_BRANCH) && defined(USE_XL24) +extern const device_t ati28800_wonderxl24_device; +#endif + +/* Cirrus Logic CL-GD 54xx */ +extern const device_t gd5402_isa_device; +extern const device_t gd5402_onboard_device; +extern const device_t gd5420_isa_device; +#if defined(DEV_BRANCH) && defined(USE_CL5422) +extern const device_t gd5422_isa_device; +extern const device_t gd5424_vlb_device; +#endif +extern const device_t gd5426_vlb_device; +extern const device_t gd5428_isa_device; +extern const device_t gd5428_vlb_device; +extern const device_t gd5429_isa_device; +extern const device_t gd5429_vlb_device; +extern const device_t gd5430_vlb_device; +extern const device_t gd5430_pci_device; +extern const device_t gd5434_isa_device; +extern const device_t gd5434_vlb_device; +extern const device_t gd5434_pci_device; +extern const device_t gd5436_pci_device; +extern const device_t gd5440_onboard_pci_device; +extern const device_t gd5440_pci_device; +extern const device_t gd5446_pci_device; +extern const device_t gd5446_stb_pci_device; +extern const device_t gd5480_pci_device; + +/* Compaq CGA */ +extern const device_t compaq_cga_device; +extern const device_t compaq_cga_2_device; + +/* Tseng ET4000AX */ +extern const device_t et4000_isa_device; +extern const device_t et4000k_isa_device; +extern const device_t et4000k_tg286_isa_device; +extern const device_t et4000_mca_device; + +/* Tseng ET4000-W32p */ +extern const device_t et4000w32p_vlb_device; +extern const device_t et4000w32p_pci_device; +extern const device_t et4000w32p_cardex_vlb_device; +extern const device_t et4000w32p_cardex_pci_device; + +/* MDSI Genius VHR */ +extern const device_t genius_device; + +/* Hercules */ +extern const device_t hercules_device; +extern const device_t herculesplus_device; +extern const device_t incolor_device; + +/* Headland GC-2xx/HT-2xx */ +extern const device_t g2_gc205_device; +extern const device_t v7_vga_1024i_device; +extern const device_t ht216_32_pb410a_device; + +/* Professional Graphics Controller */ +extern const device_t im1024_device; +extern const device_t pgc_device; + +/* Matrox Mystique */ +extern const device_t mystique_device; +extern const device_t mystique_220_device; + +/* Oak OTI-0x7 */ +extern const device_t oti037c_device; +extern const device_t oti067_device; +extern const device_t oti067_acer386_device; +extern const device_t oti067_ama932j_device; +extern const device_t oti077_device; + +/* Paradise/WD (S)VGA */ +extern const device_t paradise_pvga1a_pc2086_device; +extern const device_t paradise_pvga1a_pc3086_device; +extern const device_t paradise_pvga1a_device; +extern const device_t paradise_wd90c11_megapc_device; +extern const device_t paradise_wd90c11_device; +extern const device_t paradise_wd90c30_device; + +/* S3 9XX/8XX/Vision/Trio */ +const device_t s3_orchid_86c911_isa_device; +const device_t s3_metheus_premier_86c928_isa_device; +const device_t s3_metheus_premier_86c928_vlb_device; +const device_t s3_v7mirage_86c801_isa_device; +const device_t s3_phoenix_86c805_vlb_device; +const device_t s3_bahamas64_vlb_device; +const device_t s3_bahamas64_pci_device; +const device_t s3_9fx_vlb_device; +const device_t s3_9fx_pci_device; +const device_t s3_phoenix_trio32_vlb_device; +const device_t s3_phoenix_trio32_pci_device; +const device_t s3_phoenix_trio64_vlb_device; +const device_t s3_phoenix_trio64_onboard_pci_device; +const device_t s3_phoenix_trio64_pci_device; +const device_t s3_phoenix_vision864_pci_device; +const device_t s3_phoenix_vision864_vlb_device; +const device_t s3_diamond_stealth64_pci_device; +const device_t s3_diamond_stealth64_vlb_device; +const device_t s3_diamond_stealth64_964_pci_device; +const device_t s3_diamond_stealth64_964_vlb_device; + +/* S3 ViRGE */ +extern const device_t s3_virge_vlb_device; +extern const device_t s3_virge_pci_device; +extern const device_t s3_virge_988_vlb_device; +extern const device_t s3_virge_988_pci_device; +extern const device_t s3_virge_375_vlb_device; +extern const device_t s3_virge_375_pci_device; +extern const device_t s3_virge_375_4_vlb_device; +extern const device_t s3_virge_375_4_pci_device; + +/* Sigma Color 400 */ +extern const device_t sigma_device; + +/* Trident TGUI 94x0 */ +extern const device_t tgui9400cxi_device; +extern const device_t tgui9440_vlb_device; +extern const device_t tgui9440_pci_device; + +/* IBM PS/1 (S)VGA */ +#if defined(DEV_BRANCH) && defined(USE_TI) +extern const device_t ti_cf62011_device; +#endif +extern const device_t ibm_ps1_2121_device; + +/* Trident TVGA 8900 */ +extern const device_t tvga8900b_device; +extern const device_t tvga8900d_device; + +/* IBM VGA */ +extern const device_t vga_device; +extern const device_t ps1vga_device; +extern const device_t ps1vga_mca_device; + +/* 3DFX Voodoo Graphics */ +extern const device_t voodoo_device; + +/* Wyse 700 */ +extern const device_t wy700_device; +#endif + + #endif /*EMU_VIDEO_H*/ diff --git a/src/vnc.c b/src/vnc.c index 7b6040c4b..143b60964 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -25,7 +25,7 @@ #define HAVE_STDARG_H #include "86box.h" #include "device.h" -#include "video/video.h" +#include "video.h" #include "keyboard.h" #include "mouse.h" #include "plat.h" diff --git a/src/voice.d b/src/voice.d new file mode 100644 index 000000000..cf8e8f4e6 --- /dev/null +++ b/src/voice.d @@ -0,0 +1,4 @@ +voice.o: sound/resid-fp/voice.cc sound/resid-fp/voice.h \ + sound/resid-fp/siddefs-fp.h sound/resid-fp/wave.h \ + sound/resid-fp/envelope.h sound/resid-fp/sid.h sound/resid-fp/filter.h \ + sound/resid-fp/extfilt.h sound/resid-fp/pot.h diff --git a/src/wave.d b/src/wave.d new file mode 100644 index 000000000..cdcdfa516 --- /dev/null +++ b/src/wave.d @@ -0,0 +1,2 @@ +wave.o: sound/resid-fp/wave.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave6581_PST.d b/src/wave6581_PST.d new file mode 100644 index 000000000..038383329 --- /dev/null +++ b/src/wave6581_PST.d @@ -0,0 +1,2 @@ +wave6581_PST.o: sound/resid-fp/wave6581_PST.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave6581_PS_.d b/src/wave6581_PS_.d new file mode 100644 index 000000000..e6d28c5e4 --- /dev/null +++ b/src/wave6581_PS_.d @@ -0,0 +1,2 @@ +wave6581_PS_.o: sound/resid-fp/wave6581_PS_.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave6581_P_T.d b/src/wave6581_P_T.d new file mode 100644 index 000000000..4d4762d4b --- /dev/null +++ b/src/wave6581_P_T.d @@ -0,0 +1,2 @@ +wave6581_P_T.o: sound/resid-fp/wave6581_P_T.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave6581__ST.d b/src/wave6581__ST.d new file mode 100644 index 000000000..ae9169285 --- /dev/null +++ b/src/wave6581__ST.d @@ -0,0 +1,2 @@ +wave6581__ST.o: sound/resid-fp/wave6581__ST.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave8580_PST.d b/src/wave8580_PST.d new file mode 100644 index 000000000..53e717185 --- /dev/null +++ b/src/wave8580_PST.d @@ -0,0 +1,2 @@ +wave8580_PST.o: sound/resid-fp/wave8580_PST.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave8580_PS_.d b/src/wave8580_PS_.d new file mode 100644 index 000000000..6790db33a --- /dev/null +++ b/src/wave8580_PS_.d @@ -0,0 +1,2 @@ +wave8580_PS_.o: sound/resid-fp/wave8580_PS_.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave8580_P_T.d b/src/wave8580_P_T.d new file mode 100644 index 000000000..1b3ca8c17 --- /dev/null +++ b/src/wave8580_P_T.d @@ -0,0 +1,2 @@ +wave8580_P_T.o: sound/resid-fp/wave8580_P_T.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wave8580__ST.d b/src/wave8580__ST.d new file mode 100644 index 000000000..c933d6605 --- /dev/null +++ b/src/wave8580__ST.d @@ -0,0 +1,2 @@ +wave8580__ST.o: sound/resid-fp/wave8580__ST.cc sound/resid-fp/wave.h \ + sound/resid-fp/siddefs-fp.h diff --git a/src/wd76c10.d b/src/wd76c10.d new file mode 100644 index 000000000..690f6caa3 --- /dev/null +++ b/src/wd76c10.d @@ -0,0 +1,3 @@ +wd76c10.o: chipset/wd76c10.c 86box.h device.h timer.h cpu_common/cpu.h \ + 86box_io.h keyboard.h mem.h port_92.h serial.h floppy/fdd.h floppy/fdc.h \ + video/video.h chipset/chipset.h diff --git a/src/win.d b/src/win.d new file mode 100644 index 000000000..21aaafc50 --- /dev/null +++ b/src/win.d @@ -0,0 +1,3 @@ +win.o: win/win.c 86box.h config.h device.h keyboard.h mouse.h \ + video/video.h plat.h lang/language.h plat_midi.h ui.h win/win_d2d.h \ + win/win_sdl.h win/win.h win/resource.h diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0e2287be5..d4d7ecc0b 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.142 2020/01/18 +# Version: @(#)Makefile.mingw 1.0.143 2020/01/25 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -266,7 +266,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH := $(EXPATH) . cpu \ +VPATH := $(EXPATH) . cpu cpu_common \ cdrom chipset disk floppy game machine \ printer \ sound \ @@ -300,6 +300,17 @@ DEPFILE := win/.depends # Set up the correct toolchain flags. OPTS := $(EXTRAS) $(STUFF) +ifeq ($(WX), y) +OPTS += -I. \ + -Icpu -Icpu_common \ + -Icdrom -Ichipset -Idisk -Ifloppy -Igame -Imachine -Inetwork \ + -Iprinter -Isound -Iscsi -Ivideo -Ilang +else +OPTS += -iquote . \ + -iquote cpu -iquote cpu_common \ + -iquote cdrom -iquote chipset -iquote disk -iquote floppy -iquote game -iquote machine -iquote network \ + -iquote printer -iquote sound -iquote scsi -iquote video -iquote lang +endif ifdef EXFLAGS OPTS += $(EXFLAGS) endif @@ -338,7 +349,7 @@ else endif endif endif -AFLAGS := -msse2 -mfpmath=sse +AFLAGS := -msse2 -mfpmath=387 ifeq ($(ARM), y) DFLAGS := -march=armv7-a AOPTIM := @@ -539,8 +550,9 @@ endif # Final versions of the toolchain flags. CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ + $(AFLAGS) -pipe -fomit-frame-pointer -mstackrealign -Wall \ -fno-strict-aliasing +# -funroll-loops # Add freetyp2 references through pkgconfig CFLAGS := $(CFLAGS) `pkg-config.exe --cflags freetype2` @@ -559,7 +571,8 @@ INTELOBJ := intel_flash.o \ intel_sio.o intel_piix.o CPUOBJ := cpu.o cpu_table.o \ - 808x.o 386.o \ + 808x.o \ + 386.o 386_common.o \ 386_dynarec.o \ x86seg.o x87.o \ $(DYNARECOBJ) @@ -588,7 +601,9 @@ DEVOBJ := bugger.o ibm_5161.o isamem.o isartc.o lpt.o $(SERIAL) \ sio_acc3221.o \ sio_fdc37c66x.o sio_fdc37c669.o \ sio_fdc37c93x.o \ - sio_pc87306.o sio_w83877f.o \ + sio_pc87306.o \ + sio_w83787f.o \ + sio_w83877f.o sio_w83977f.o \ sio_um8669f.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ @@ -788,7 +803,7 @@ all: $(PROG).exe pcap_if.exe $(PROG).exe: $(OBJ) 86Box.res @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) + @$(CC) -o $(PROG).exe $(OBJ) 86Box.res $(LIBS) -pipe ifneq ($(DEBUG), y) @$(STRIP) $(PROG).exe endif diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 62713f351..27588540a 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.141 2020/01/14 +# Version: @(#)Makefile.mingw 1.0.142 2020/01/25 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -266,7 +266,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH := $(EXPATH) . cpu_new \ +VPATH := $(EXPATH) . cpu_new cpu_common \ cdrom chipset disk floppy game machine \ printer \ sound \ @@ -300,6 +300,17 @@ DEPFILE := win/.depends # Set up the correct toolchain flags. OPTS := $(EXTRAS) $(STUFF) +ifeq ($(WX), y) +OPTS += -I. \ + -Icpu_new -Icpu_common \ + -Icdrom -Ichipset -Idisk -Ifloppy -Igame -Imachine -Inetwork \ + -Iprinter -Isound -Iscsi -Ivideo -Ilang +else +OPTS += -iquote . \ + -iquote cpu_new -iquote cpu_common \ + -iquote cdrom -iquote chipset -iquote disk -iquote floppy -iquote game -iquote machine -iquote network \ + -iquote printer -iquote sound -iquote scsi -iquote video -iquote lang +endif ifdef EXFLAGS OPTS += $(EXFLAGS) endif @@ -558,14 +569,15 @@ CXXFLAGS := $(CFLAGS) # Create the (final) list of objects to build. # ######################################################################### MAINOBJ := pc.o config.o random.o timer.o io.o apm_new.o dma.o nmi.o \ - pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem_new.o \ + pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \ rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o $(VNCOBJ) $(RDPOBJ) INTELOBJ := intel_flash.o \ intel_sio.o intel_piix.o CPUOBJ := cpu.o cpu_table.o \ - 808x.o 386.o 386_common.o \ + 808x.o \ + 386.o 386_common.o \ 386_dynarec.o \ x86seg.o x87.o \ $(DYNARECOBJ) @@ -575,7 +587,7 @@ CHIPSETOBJ := acc2168.o acer_m3a.o ali1429.o headland.o \ sis_85c471.o sis_85c496.o \ via_mvp3.o wd76c10.o -MCHOBJ := machine.o machine_table_new.o \ +MCHOBJ := machine.o machine_table.o \ m_xt.o m_xt_compaq.o \ m_xt_t1000.o m_xt_t1000_vid.o \ m_xt_xi8088.o m_xt_zenith.o \ @@ -594,7 +606,9 @@ DEVOBJ := bugger.o ibm_5161.o isamem.o isartc.o lpt.o $(SERIAL) \ sio_acc3221.o \ sio_fdc37c66x.o sio_fdc37c669.o \ sio_fdc37c93x.o \ - sio_pc87306.o sio_w83877f.o \ + sio_pc87306.o \ + sio_w83787f.o \ + sio_w83877f.o sio_w83977f.o \ sio_um8669f.o \ keyboard.o \ keyboard_xt.o keyboard_at.o \ diff --git a/src/win/win.c b/src/win/win.c index cfbdab264..4197edd4c 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -30,18 +30,18 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../video/video.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "keyboard.h" +#include "mouse.h" +#include "video.h" #define GLOBAL -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #ifdef USE_VNC -# include "../vnc.h" +# include "vnc.h" #endif # include "win_d2d.h" # include "win_sdl.h" diff --git a/src/win/win_about.c b/src/win/win_about.c index ae0eea162..b714cf334 100644 --- a/src/win/win_about.c +++ b/src/win/win_about.c @@ -26,8 +26,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index b027f463f..e808ced53 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -27,14 +27,14 @@ #include #include #include -#include "../config.h" -#include "../disk/hdd.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "../scsi/scsi_disk.h" -#include "../plat.h" -#include "../ui.h" +#include "config.h" +#include "hdd.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "scsi_disk.h" +#include "plat.h" +#include "ui.h" #include "win.h" diff --git a/src/win/win_crashdump.c b/src/win/win_crashdump.c index 32944dbd0..cbec1b680 100644 --- a/src/win/win_crashdump.c +++ b/src/win/win_crashdump.c @@ -25,8 +25,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_d2d.c b/src/win/win_d2d.c index 038ef739c..45ff1e83b 100644 --- a/src/win/win_d2d.c +++ b/src/win/win_d2d.c @@ -27,12 +27,12 @@ #undef BITMAP #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../video/video.h" -#include "../plat.h" -#include "../plat_dynld.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "video.h" +#include "plat.h" +#include "plat_dynld.h" +#include "ui.h" #include "win.h" #include "win_d2d.h" diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index e5e379d6c..fa925eb33 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -21,12 +21,12 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #include "win.h" #include diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c index bf93b474c..5d867f67f 100644 --- a/src/win/win_dialog.c +++ b/src/win/win_dialog.c @@ -27,10 +27,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "ui.h" #include "win.h" diff --git a/src/win/win_discord.c b/src/win/win_discord.c index c174413a8..04253b5b6 100644 --- a/src/win/win_discord.c +++ b/src/win/win_discord.c @@ -22,15 +22,11 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#ifdef USE_NEW_DYNAREC - #include "../cpu_new/cpu.h" -#else - #include "../cpu/cpu.h" -#endif -#include "../machine/machine.h" -#include "../plat.h" -#include "../plat_dynld.h" +#include "86box.h" +#include "cpu.h" +#include "machine.h" +#include "plat.h" +#include "plat_dynld.h" #include "win_discord.h" #include "discord_game_sdk.h" diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index e258ebe19..b5e89aaff 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -22,8 +22,8 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../plat_dynld.h" +#include "86box.h" +#include "plat_dynld.h" #ifdef ENABLE_DYNLD_LOG diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 499f19903..437b506e6 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -23,10 +23,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../game/gameport.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "gameport.h" #include "win.h" diff --git a/src/win/win_joystick_xinput.cpp b/src/win/win_joystick_xinput.cpp index 237cab23c..5d3e2fbbb 100644 --- a/src/win/win_joystick_xinput.cpp +++ b/src/win/win_joystick_xinput.cpp @@ -24,10 +24,10 @@ #include #include #define HAVE_STDARG_H -#include "../86box.h" -#include "../device.h" -#include "../plat.h" -#include "../game/gameport.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "gameport.h" #include "win.h" #define XINPUT_MAX_JOYSTICKS 4 diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 0d7474f59..b048afa27 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -7,11 +7,11 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../game/gameport.h" -#include "../plat.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "gameport.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index eaf4ddac4..8fb761a44 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -24,10 +24,10 @@ #include #include #include -#include "../86box.h" -#include "../device.h" -#include "../keyboard.h" -#include "../plat.h" +#include "86box.h" +#include "device.h" +#include "keyboard.h" +#include "plat.h" #include "win.h" diff --git a/src/win/win_midi.c b/src/win/win_midi.c index dace62b0e..c38f444fd 100644 --- a/src/win/win_midi.c +++ b/src/win/win_midi.c @@ -4,11 +4,11 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../sound/midi.h" -#include "../plat.h" -#include "../plat_midi.h" +#include "86box.h" +#include "config.h" +#include "midi.h" +#include "plat.h" +#include "plat_midi.h" typedef struct diff --git a/src/win/win_mouse.c b/src/win/win_mouse.c index 2ca004e9f..f58f4be82 100644 --- a/src/win/win_mouse.c +++ b/src/win/win_mouse.c @@ -22,9 +22,9 @@ #include #include #include -#include "../86box.h" -#include "../mouse.h" -#include "../plat.h" +#include "86box.h" +#include "mouse.h" +#include "plat.h" #include "win.h" int mouse_capture; diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 4bb7b30f9..bbae1551e 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -25,12 +25,12 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" -#include "../random.h" -#include "../ui.h" -#include "../scsi/scsi_device.h" -#include "../disk/zip.h" +#include "86box.h" +#include "plat.h" +#include "random.h" +#include "ui.h" +#include "scsi_device.h" +#include "zip.h" #include "win.h" diff --git a/src/win/win_opendir.c b/src/win/win_opendir.c index bcd683c3d..74309eb25 100644 --- a/src/win/win_opendir.c +++ b/src/win/win_opendir.c @@ -25,8 +25,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" #include "plat_dir.h" diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 77b5c8a2f..f4c415d11 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -62,12 +62,12 @@ /* 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" -#include "../plat_dynld.h" -#include "../video/video.h" -#include "../ui.h" +#include "86box.h" +#include "device.h" +#include "plat.h" +#include "plat_dynld.h" +#include "video.h" +#include "ui.h" #include "win.h" #include "win_sdl.h" diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 69f054acd..0d79a7124 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -30,38 +30,36 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../cpu/cpu.h" -#include "../mem.h" -#include "../rom.h" -#include "../device.h" -#include "../timer.h" -#include "../nvr.h" -#include "../machine/machine.h" -#include "../game/gameport.h" -#include "../isamem.h" -#include "../isartc.h" -#include "../lpt.h" -#include "../mouse.h" -#include "../scsi/scsi.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" -#include "../disk/zip.h" -#include "../floppy/fdd.h" -#include "../network/network.h" -#include "../sound/sound.h" -#include "../sound/midi.h" -#include "../sound/snd_mpu401.h" -#include "../sound/snd_gus.h" -#include "../video/video.h" -#include "../video/vid_voodoo.h" -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "cpu.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "timer.h" +#include "nvr.h" +#include "machine.h" +#include "gameport.h" +#include "isamem.h" +#include "isartc.h" +#include "lpt.h" +#include "mouse.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "hdd.h" +#include "hdc.h" +#include "hdc_ide.h" +#include "zip.h" +#include "fdd.h" +#include "network.h" +#include "sound.h" +#include "midi.h" +#include "snd_mpu401.h" +#include "video.h" +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #include "win.h" diff --git a/src/win/win_snd_gain.c b/src/win/win_snd_gain.c index 0dc4e5dcc..7f23a1aee 100644 --- a/src/win/win_snd_gain.c +++ b/src/win/win_snd_gain.c @@ -25,10 +25,10 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../plat.h" -#include "../sound/sound.h" +#include "86box.h" +#include "config.h" +#include "plat.h" +#include "sound.h" #include "win.h" diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index ede2cb271..43554f159 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -28,27 +28,27 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../cpu/cpu.h" -#include "../device.h" -#include "../machine/machine.h" -#include "../timer.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../floppy/fdd.h" -#include "../floppy/fdd_86f.h" -#include "../scsi/scsi.h" -#include "../scsi/scsi_device.h" -#include "../cdrom/cdrom.h" -#include "../disk/zip.h" -#include "../cdrom/cdrom_image.h" -#include "../scsi/scsi_disk.h" -#include "../network/network.h" -#include "../video/video.h" -#include "../sound/sound.h" -#include "../plat.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "cpu.h" +#include "device.h" +#include "machine.h" +#include "timer.h" +#include "hdd.h" +#include "hdc.h" +#include "fdd.h" +#include "fdd_86f.h" +#include "scsi.h" +#include "scsi_device.h" +#include "cdrom.h" +#include "zip.h" +#include "cdrom_image.h" +#include "scsi_disk.h" +#include "network.h" +#include "video.h" +#include "sound.h" +#include "plat.h" +#include "ui.h" #include "win.h" #ifndef GWL_WNDPROC diff --git a/src/win/win_thread.c b/src/win/win_thread.c index 2f885ec04..31a087cab 100644 --- a/src/win/win_thread.c +++ b/src/win/win_thread.c @@ -27,8 +27,8 @@ #include #include #include -#include "../86box.h" -#include "../plat.h" +#include "86box.h" +#include "plat.h" typedef struct { diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 812e4c2cb..cfe5d37fb 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -28,16 +28,16 @@ #include #include #include -#include "../86box.h" -#include "../config.h" -#include "../device.h" -#include "../keyboard.h" -#include "../mouse.h" -#include "../video/video.h" -#include "../video/vid_ega.h" // for update_overscan -#include "../plat.h" -#include "../plat_midi.h" -#include "../ui.h" +#include "86box.h" +#include "config.h" +#include "device.h" +#include "keyboard.h" +#include "mouse.h" +#include "video.h" +#include "vid_ega.h" // for update_overscan +#include "plat.h" +#include "plat_midi.h" +#include "ui.h" #include "win.h" #ifdef USE_DISCORD # include "win_discord.h" diff --git a/src/win_about.d b/src/win_about.d new file mode 100644 index 000000000..9d2c914c7 --- /dev/null +++ b/src/win_about.d @@ -0,0 +1,2 @@ +win_about.o: win/win_about.c 86box.h plat.h lang/language.h win/win.h \ + win/resource.h diff --git a/src/win_cdrom.d b/src/win_cdrom.d new file mode 100644 index 000000000..9dd9a172a --- /dev/null +++ b/src/win_cdrom.d @@ -0,0 +1,3 @@ +win_cdrom.o: win/win_cdrom.c config.h disk/hdd.h scsi/scsi_device.h \ + cdrom/cdrom.h disk/zip.h scsi/scsi_disk.h plat.h lang/language.h ui.h \ + win/win.h win/resource.h diff --git a/src/win_devconf.d b/src/win_devconf.d new file mode 100644 index 000000000..4b4b8dc18 --- /dev/null +++ b/src/win_devconf.d @@ -0,0 +1,2 @@ +win_devconf.o: win/win_devconf.c 86box.h config.h device.h plat.h \ + lang/language.h plat_midi.h ui.h win/win.h win/resource.h diff --git a/src/win_dialog.d b/src/win_dialog.d new file mode 100644 index 000000000..a86b34d1c --- /dev/null +++ b/src/win_dialog.d @@ -0,0 +1,2 @@ +win_dialog.o: win/win_dialog.c 86box.h device.h plat.h lang/language.h \ + ui.h win/win.h win/resource.h diff --git a/src/win_discord.d b/src/win_discord.d new file mode 100644 index 000000000..404f3acdd --- /dev/null +++ b/src/win_discord.d @@ -0,0 +1,3 @@ +win_discord.o: win/win_discord.c 86box.h cpu_common/cpu.h \ + machine/machine.h plat.h lang/language.h plat_dynld.h win/win_discord.h \ + win/discord_game_sdk.h diff --git a/src/win_dynld.d b/src/win_dynld.d new file mode 100644 index 000000000..0bea1e35a --- /dev/null +++ b/src/win_dynld.d @@ -0,0 +1 @@ +win_dynld.o: win/win_dynld.c 86box.h plat_dynld.h diff --git a/src/win_joystick.d b/src/win_joystick.d new file mode 100644 index 000000000..f4b16288b --- /dev/null +++ b/src/win_joystick.d @@ -0,0 +1,2 @@ +win_joystick.o: win/win_joystick.cpp 86box.h device.h plat.h \ + lang/language.h game/gameport.h win/win.h win/resource.h diff --git a/src/win_jsconf.d b/src/win_jsconf.d new file mode 100644 index 000000000..97e13bb1a --- /dev/null +++ b/src/win_jsconf.d @@ -0,0 +1,2 @@ +win_jsconf.o: win/win_jsconf.c 86box.h config.h device.h game/gameport.h \ + plat.h lang/language.h win/win.h win/resource.h diff --git a/src/win_keyboard.d b/src/win_keyboard.d new file mode 100644 index 000000000..74d66bbf2 --- /dev/null +++ b/src/win_keyboard.d @@ -0,0 +1,2 @@ +win_keyboard.o: win/win_keyboard.c 86box.h device.h keyboard.h plat.h \ + lang/language.h win/win.h win/resource.h diff --git a/src/win_midi.d b/src/win_midi.d new file mode 100644 index 000000000..2891c9398 --- /dev/null +++ b/src/win_midi.d @@ -0,0 +1,2 @@ +win_midi.o: win/win_midi.c 86box.h config.h sound/midi.h plat.h \ + lang/language.h plat_midi.h diff --git a/src/win_mouse.d b/src/win_mouse.d new file mode 100644 index 000000000..8b8fd91de --- /dev/null +++ b/src/win_mouse.d @@ -0,0 +1,2 @@ +win_mouse.o: win/win_mouse.c 86box.h mouse.h plat.h lang/language.h \ + win/win.h win/resource.h diff --git a/src/win_new_floppy.d b/src/win_new_floppy.d new file mode 100644 index 000000000..5558bd5eb --- /dev/null +++ b/src/win_new_floppy.d @@ -0,0 +1,2 @@ +win_new_floppy.o: win/win_new_floppy.c 86box.h plat.h lang/language.h \ + random.h ui.h scsi/scsi_device.h disk/zip.h win/win.h win/resource.h diff --git a/src/win_sdl.d b/src/win_sdl.d new file mode 100644 index 000000000..ac418633e --- /dev/null +++ b/src/win_sdl.d @@ -0,0 +1,2 @@ +win_sdl.o: win/win_sdl.c 86box.h device.h plat.h lang/language.h \ + plat_dynld.h video/video.h ui.h win/win.h win/resource.h win/win_sdl.h diff --git a/src/win_settings.d b/src/win_settings.d new file mode 100644 index 000000000..a28ef3ce8 --- /dev/null +++ b/src/win_settings.d @@ -0,0 +1,7 @@ +win_settings.o: win/win_settings.c 86box.h config.h cpu_common/cpu.h \ + mem.h rom.h device.h timer.h nvr.h machine/machine.h game/gameport.h \ + isamem.h isartc.h lpt.h mouse.h scsi/scsi.h scsi/scsi_device.h \ + cdrom/cdrom.h disk/hdd.h disk/hdc.h disk/hdc_ide.h disk/zip.h \ + floppy/fdd.h network/network.h sound/sound.h sound/midi.h \ + sound/snd_mpu401.h video/video.h plat.h lang/language.h plat_midi.h ui.h \ + win/win.h win/resource.h diff --git a/src/win_snd_gain.d b/src/win_snd_gain.d new file mode 100644 index 000000000..bea6ecdc4 --- /dev/null +++ b/src/win_snd_gain.d @@ -0,0 +1,2 @@ +win_snd_gain.o: win/win_snd_gain.c 86box.h config.h plat.h \ + lang/language.h sound/sound.h win/win.h win/resource.h diff --git a/src/win_stbar.d b/src/win_stbar.d new file mode 100644 index 000000000..e2da1399c --- /dev/null +++ b/src/win_stbar.d @@ -0,0 +1,5 @@ +win_stbar.o: win/win_stbar.c 86box.h config.h cpu_common/cpu.h device.h \ + machine/machine.h timer.h disk/hdd.h disk/hdc.h floppy/fdd.h \ + floppy/fdd_86f.h scsi/scsi.h scsi/scsi_device.h cdrom/cdrom.h disk/zip.h \ + cdrom/cdrom_image.h scsi/scsi_disk.h network/network.h video/video.h \ + sound/sound.h plat.h lang/language.h ui.h win/win.h win/resource.h diff --git a/src/win_thread.d b/src/win_thread.d new file mode 100644 index 000000000..4c15afbb7 --- /dev/null +++ b/src/win_thread.d @@ -0,0 +1 @@ +win_thread.o: win/win_thread.c 86box.h plat.h lang/language.h diff --git a/src/win_ui.d b/src/win_ui.d new file mode 100644 index 000000000..f051c11a4 --- /dev/null +++ b/src/win_ui.d @@ -0,0 +1,3 @@ +win_ui.o: win/win_ui.c 86box.h config.h device.h keyboard.h mouse.h \ + video/video.h video/vid_ega.h plat.h lang/language.h plat_midi.h ui.h \ + win/win.h win/resource.h win/win_discord.h diff --git a/src/x86.txt b/src/x86.txt new file mode 100644 index 000000000..37d6b6d8b --- /dev/null +++ b/src/x86.txt @@ -0,0 +1,785 @@ +Comparing files CPU\codegen.h and CPU_NEW\CODEGEN.H +***** CPU\codegen.h +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen.h 1.0.2 2018/03/14 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#ifndef _CODEGEN_H_ +#define _CODEGEN_H_ +***** CPU_NEW\CODEGEN.H +#ifndef _CODEGEN_H_ +#define _CODEGEN_H_ +***** + +***** CPU\codegen.h + +#include "../mem.h" +#include "../cpu_common/x86_ops.h" +***** CPU_NEW\CODEGEN.H + +#include "mem.h" +#include "../cpu_common/x86_ops.h" +***** + +***** CPU\codegen.h + +#ifdef __amd64__ +#include "codegen_x86-64.h" +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 +#include "codegen_x86.h" +#else +#error Dynamic recompiler not implemented on your platform +#endif + +/*Handling self-modifying code (of which there is a lot on x86) : +***** CPU_NEW\CODEGEN.H + +/*Handling self-modifying code (of which there is a lot on x86) : +***** + +***** CPU\codegen.h +{ + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; + uint64_t cmp; + + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + struct codeblock_t *prev, *next; + struct codeblock_t *prev_2, *next_2; + + /*Pointers for codeblock tree, used to search for blocks when hash lookup +***** CPU_NEW\CODEGEN.H +{ + uint32_t pc; + uint32_t _cs; + uint32_t phys, phys_2; + uint16_t status; + uint16_t flags; + uint8_t ins; + uint8_t TOP; + + /*Pointers for codeblock tree, used to search for blocks when hash lookup +***** + +***** CPU\codegen.h + fails.*/ + struct codeblock_t *parent, *left, *right; + + int pnt; + int ins; + + int valid; + + int was_recompiled; + int TOP; + + uint32_t pc; + uint32_t _cs; + uint32_t endpc; + uint32_t phys, phys_2; + uint32_t status; + uint32_t flags; + + uint8_t data[2048]; +} codeblock_t; +***** CPU_NEW\CODEGEN.H + fails.*/ + uint16_t parent, left, right; + + uint8_t *data; + + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; + + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + uint16_t prev, next; + uint16_t prev_2, next_2; + + /*First mem_block_t used by this block. Any subsequent mem_block_ts + will be in the list starting at head_mem_block->next.*/ + struct mem_block_t *head_mem_block; +} codeblock_t; +***** + +***** CPU\codegen.h + +/*Code block uses FPU*/ +***** CPU_NEW\CODEGEN.H + +extern codeblock_t *codeblock; + +extern uint16_t *codeblock_hash; + +extern uint8_t *block_write_data; + +/*Code block uses FPU*/ +***** + +***** CPU\codegen.h +#define CODEBLOCK_STATIC_TOP 2 + +***** CPU_NEW\CODEGEN.H +#define CODEBLOCK_STATIC_TOP 2 +/*Code block has been compiled*/ +#define CODEBLOCK_WAS_RECOMPILED 4 +/*Code block is in free list and is not valid*/ +#define CODEBLOCK_IN_FREE_LIST 8 +/*Code block spans two pages, page_mask2 and dirty_mask2 are valid*/ +#define CODEBLOCK_HAS_PAGE2 0x10 +/*Code block is using a byte mask for code present and dirty*/ +#define CODEBLOCK_BYTE_MASK 0x20 +/*Code block is in dirty list*/ +#define CODEBLOCK_IN_DIRTY_LIST 0x40 +/*Code block is not inlining immediate parameters, parameters must be fetched from memory*/ +#define CODEBLOCK_NO_IMMEDIATES 0x80 + +#define BLOCK_PC_INVALID 0xffffffff + +#define BLOCK_INVALID 0 + +static inline int get_block_nr(codeblock_t *block) +{ + return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); +} + +***** + +***** CPU\codegen.h +{ + codeblock_t *block = pages[phys >> 12].head; + uint64_t a = _cs | ((uint64_t)phys << 32); +***** CPU_NEW\CODEGEN.H +{ + codeblock_t *block; + uint64_t a = _cs | ((uint64_t)phys << 32); +***** + +***** CPU\codegen.h + + while (block) +***** CPU_NEW\CODEGEN.H + + if (!pages[phys >> 12].head) + return NULL; + + block = &codeblock[pages[phys >> 12].head]; + while (block) +***** + +***** CPU\codegen.h + { + if (a == block->cmp) + { +***** CPU_NEW\CODEGEN.H + { + uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); + if (a == block_cmp) + { +***** + +***** CPU\codegen.h + } + if (a < block->cmp) + block = block->left; + else + block = block->right; + } +***** CPU_NEW\CODEGEN.H + } + if (a < block_cmp) + block = block->left ? &codeblock[block->left] : NULL; + else + block = block->right ? &codeblock[block->right] : NULL; + } +***** + +***** CPU\codegen.h +{ + codeblock_t *block = pages[new_block->phys >> 12].head; + uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); + new_block->cmp = a; + + if (!block) + { + pages[new_block->phys >> 12].head = new_block; + new_block->parent = new_block->left = new_block->right = NULL; + } +***** CPU_NEW\CODEGEN.H +{ + codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; + uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); + + if (!pages[new_block->phys >> 12].head) + { + pages[new_block->phys >> 12].head = get_block_nr(new_block); + new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + codeblock_t *old_block = NULL; + +***** CPU_NEW\CODEGEN.H + codeblock_t *old_block = NULL; + uint64_t old_block_cmp = 0; + +***** + +***** CPU\codegen.h + old_block = block; + if (a < old_block->cmp) + block = block->left; + else + block = block->right; + } +***** CPU_NEW\CODEGEN.H + old_block = block; + old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); + + if (a < old_block_cmp) + block = block->left ? &codeblock[block->left] : NULL; + else + block = block->right ? &codeblock[block->right] : NULL; + } +***** + +***** CPU\codegen.h + + if (a < old_block->cmp) + old_block->left = new_block; + else + old_block->right = new_block; + + new_block->parent = old_block; + new_block->left = new_block->right = NULL; + } +***** CPU_NEW\CODEGEN.H + + if (a < old_block_cmp) + old_block->left = get_block_nr(new_block); + else + old_block->right = get_block_nr(new_block); + + new_block->parent = get_block_nr(old_block); + new_block->left = new_block->right = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h +{ + codeblock_t *parent = block->parent; + +***** CPU_NEW\CODEGEN.H +{ + uint16_t parent_nr = block->parent; + codeblock_t *parent; + + if (block->parent) + parent = &codeblock[block->parent]; + else + parent = NULL; + +***** + +***** CPU\codegen.h + if (!parent) + pages[block->phys >> 12].head = NULL; + else +***** CPU_NEW\CODEGEN.H + if (!parent) + pages[block->phys >> 12].head = BLOCK_INVALID; + else +***** + +***** CPU\codegen.h + { + if (parent->left == block) + parent->left = NULL; + if (parent->right == block) + parent->right = NULL; + } +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = BLOCK_INVALID; + if (parent->right == block_nr) + parent->right = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + /*Only right node*/ + if (!parent) + { +***** CPU_NEW\CODEGEN.H + /*Only right node*/ + if (!parent_nr) + { +***** + +***** CPU\codegen.h + pages[block->phys >> 12].head = block->right; + pages[block->phys >> 12].head->parent = NULL; + } +***** CPU_NEW\CODEGEN.H + pages[block->phys >> 12].head = block->right; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + { + if (parent->left == block) + { +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + { +***** + +***** CPU\codegen.h + parent->left = block->right; + parent->left->parent = parent; + } + if (parent->right == block) + { +***** CPU_NEW\CODEGEN.H + parent->left = block->right; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) + { +***** + +***** CPU\codegen.h + parent->right = block->right; + parent->right->parent = parent; + } +***** CPU_NEW\CODEGEN.H + parent->right = block->right; + codeblock[parent->right].parent = parent_nr; + } +***** + +***** CPU\codegen.h + /*Only left node*/ + if (!parent) + { +***** CPU_NEW\CODEGEN.H + /*Only left node*/ + if (!parent_nr) + { +***** + +***** CPU\codegen.h + pages[block->phys >> 12].head = block->left; + pages[block->phys >> 12].head->parent = NULL; + } +***** CPU_NEW\CODEGEN.H + pages[block->phys >> 12].head = block->left; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } +***** + +***** CPU\codegen.h + { + if (parent->left == block) + { +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + { +***** + +***** CPU\codegen.h + parent->left = block->left; + parent->left->parent = parent; + } + if (parent->right == block) + { +***** CPU_NEW\CODEGEN.H + parent->left = block->left; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) + { +***** + +***** CPU\codegen.h + parent->right = block->left; + parent->right->parent = parent; + } +***** CPU_NEW\CODEGEN.H + parent->right = block->left; + codeblock[parent->right].parent = parent_nr; + } +***** + +***** CPU\codegen.h + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = block->right, *highest; + codeblock_t *old_parent; + +***** CPU_NEW\CODEGEN.H + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = &codeblock[block->right], *highest; + codeblock_t *old_parent; + uint16_t lowest_nr; + +***** + +***** CPU\codegen.h + while (lowest->left) + lowest = lowest->left; + + old_parent = lowest->parent; + +***** CPU_NEW\CODEGEN.H + while (lowest->left) + lowest = &codeblock[lowest->left]; + lowest_nr = get_block_nr(lowest); + + old_parent = &codeblock[lowest->parent]; + +***** + +***** CPU\codegen.h + /*Replace deleted node with lowest node*/ + if (!parent) + pages[block->phys >> 12].head = lowest; + else +***** CPU_NEW\CODEGEN.H + /*Replace deleted node with lowest node*/ + if (!parent_nr) + pages[block->phys >> 12].head = lowest_nr; + else +***** + +***** CPU\codegen.h + { + if (parent->left == block) + parent->left = lowest; + if (parent->right == block) + parent->right = lowest; + } +***** CPU_NEW\CODEGEN.H + { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = lowest_nr; + if (parent->right == block_nr) + parent->right = lowest_nr; + } +***** + +***** CPU\codegen.h + + lowest->parent = parent; + lowest->left = block->left; +***** CPU_NEW\CODEGEN.H + + lowest->parent = parent_nr; + lowest->left = block->left; +***** + +***** CPU\codegen.h + if (lowest->left) + lowest->left->parent = lowest; + + old_parent->left = NULL; + + highest = lowest->right; + if (!highest) + { + if (lowest != block->right) + { +***** CPU_NEW\CODEGEN.H + if (lowest->left) + codeblock[lowest->left].parent = lowest_nr; + + old_parent->left = BLOCK_INVALID; + + highest = &codeblock[lowest->right]; + if (!lowest->right) + { + if (lowest_nr != block->right) + { +***** + +***** CPU\codegen.h + lowest->right = block->right; + block->right->parent = lowest; + } +***** CPU_NEW\CODEGEN.H + lowest->right = block->right; + codeblock[block->right].parent = lowest_nr; + } +***** + +***** CPU\codegen.h + while (highest->right) + highest = highest->right; + + if (block->right && block->right != lowest) + { +***** CPU_NEW\CODEGEN.H + while (highest->right) + highest = &codeblock[highest->right]; + + if (block->right && block->right != lowest_nr) + { +***** + +***** CPU\codegen.h + highest->right = block->right; + block->right->parent = highest; + } +***** CPU_NEW\CODEGEN.H + highest->right = block->right; + codeblock[block->right].parent = get_block_nr(highest); + } +***** + +***** CPU\codegen.h + +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 4 + +extern codeblock_t *codeblock; + +extern codeblock_t **codeblock_hash; + +***** CPU_NEW\CODEGEN.H + +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 6 + +void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len); + +static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) +{ + if (len == 1) + { + if (block->flags & CODEBLOCK_BYTE_MASK) + { + if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ + block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); + } + else + { + if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ + block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + } + } + else + codegen_mark_code_present_multibyte(block, start_pc, len); +} + +***** + +***** CPU\codegen.h +void codegen_init(); +void codegen_reset(); +***** CPU_NEW\CODEGEN.H +void codegen_init(); +void codegen_close(); +void codegen_reset(); +***** + +***** CPU\codegen.h +void codegen_block_end(); +void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +***** CPU_NEW\CODEGEN.H +void codegen_block_end(); +void codegen_delete_block(codeblock_t *block); +void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); +***** + +***** CPU\codegen.h +void codegen_flush(); +void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); + +***** CPU_NEW\CODEGEN.H +void codegen_flush(); +void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); +struct ir_data_t; +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t + op_32, int stack_offset); +void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); + +int codegen_purge_purgable_list(); +/*Delete a random code block to free memory. This is obviously quite expensive, and + will only be called when the allocator is out of memory*/ +void codegen_delete_random_block(int required_mem_block); + +***** + +***** CPU\codegen.h +extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); +extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); +extern void (*codegen_timing_block_start)(); +***** CPU_NEW\CODEGEN.H +extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); +extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); +extern void (*codegen_timing_block_start)(); +***** + +***** CPU\codegen.h +extern void (*codegen_timing_block_end)(); + +***** CPU_NEW\CODEGEN.H +extern void (*codegen_timing_block_end)(); +extern int (*codegen_timing_jump_cycles)(); + +***** + +***** CPU\codegen.h + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); + void (*block_start)(); +***** CPU_NEW\CODEGEN.H + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); + void (*block_start)(); +***** + +***** CPU\codegen.h + void (*block_end)(); +} codegen_timing_t; +***** CPU_NEW\CODEGEN.H + void (*block_end)(); + int (*jump_cycles)(); +} codegen_timing_t; +***** + +***** CPU\codegen.h +extern codegen_timing_t codegen_timing_winchip; + +***** CPU_NEW\CODEGEN.H +extern codegen_timing_t codegen_timing_winchip; +extern codegen_timing_t codegen_timing_winchip2; +extern codegen_timing_t codegen_timing_k6; + +***** + +***** CPU\codegen.h + +static inline void addbyte(uint8_t val) +{ + codeblock[block_current].data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addword(uint16_t val) +{ + uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos]; + *p = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addlong(uint32_t val) +{ + uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos]; + *p = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addquad(uint64_t val) +{ + uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos]; + *p = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +***** CPU_NEW\CODEGEN.H + +/*Current physical page of block being recompiled. -1 if no recompilation taking place */ +***** + +***** CPU\codegen.h + +#endif +***** CPU_NEW\CODEGEN.H + +void codegen_generate_reset(); + +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); +void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); + +#ifdef DEBUG_EXTRA +extern uint32_t instr_counts[256*256]; +#endif +***** + +***** CPU\codegen.h +***** CPU_NEW\CODEGEN.H + +#endif +***** + diff --git a/src/x86_flags.txt b/src/x86_flags.txt new file mode 100644 index 000000000..a538f84dc --- /dev/null +++ b/src/x86_flags.txt @@ -0,0 +1,835 @@ +Comparing files CPU\x86_flags.h and CPU_NEW\X86_FLAGS.H +***** CPU\x86_flags.h +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +extern int tempc; + +***** CPU_NEW\X86_FLAGS.H +extern int tempc; + +***** + +***** CPU\x86_flags.h + + FLAGS_INC8, +***** CPU_NEW\X86_FLAGS.H + + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, + + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, + + FLAGS_INC8, +***** + +***** CPU\x86_flags.h + FLAGS_DEC16, + FLAGS_DEC32 +}; +***** CPU_NEW\X86_FLAGS.H + FLAGS_DEC16, + FLAGS_DEC32, + + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, + + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 +}; +***** + +***** CPU\x86_flags.h + +static __inline int ZF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int ZF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_DEC32: + return !cpu_state.flags_res; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return !cpu_state.flags_res; +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & Z_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & Z_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int NF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int NF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_DEC8: + return cpu_state.flags_res & 0x80; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC8: + case FLAGS_ADC8: + case FLAGS_SBC8: + return cpu_state.flags_res & 0x80; +***** + +***** CPU\x86_flags.h + case FLAGS_DEC16: + return cpu_state.flags_res & 0x8000; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC16: + case FLAGS_ADC16: + case FLAGS_SBC16: + return cpu_state.flags_res & 0x8000; +***** + +***** CPU\x86_flags.h + case FLAGS_DEC32: + return cpu_state.flags_res & 0x80000000; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC32: + case FLAGS_ADC32: + case FLAGS_SBC32: + return cpu_state.flags_res & 0x80000000; +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & N_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & N_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int PF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int PF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_DEC32: + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; +***** CPU_NEW\X86_FLAGS.H + case FLAGS_DEC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & P_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & P_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int VF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int VF_SET() +{ +***** + +***** CPU\x86_flags.h + + case FLAGS_ADD8: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ADC8: + case FLAGS_ADD8: +***** + +***** CPU\x86_flags.h +0x80); + case FLAGS_ADD16: + case FLAGS_INC16: +***** CPU_NEW\X86_FLAGS.H +0x80); + case FLAGS_ADC16: + case FLAGS_ADD16: + case FLAGS_INC16: +***** + +***** CPU\x86_flags.h +& 0x8000); + case FLAGS_ADD32: + case FLAGS_INC32: +***** CPU_NEW\X86_FLAGS.H +& 0x8000); + case FLAGS_ADC32: + case FLAGS_ADD32: + case FLAGS_INC32: +***** + +***** CPU\x86_flags.h +es) & 0x80000000); + + case FLAGS_SUB8: +***** CPU_NEW\X86_FLAGS.H +es) & 0x80000000); + + case FLAGS_SBC8: + case FLAGS_SUB8: +***** + +***** CPU\x86_flags.h + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SUB16: + case FLAGS_DEC16: +***** CPU_NEW\X86_FLAGS.H + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SBC16: + case FLAGS_SUB16: + case FLAGS_DEC16: +***** + +***** CPU\x86_flags.h + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SUB32: + case FLAGS_DEC32: +***** CPU_NEW\X86_FLAGS.H + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SBC32: + case FLAGS_SUB32: + case FLAGS_DEC32: +***** + +***** CPU\x86_flags.h + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & V_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & V_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int AF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int AF_SET() +{ +***** + +***** CPU\x86_flags.h + + case FLAGS_SUB8: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + + case FLAGS_SUB8: +***** + +***** CPU\x86_flags.h + + case FLAGS_UNKNOWN: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || + ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: +***** + +***** CPU\x86_flags.h + return cpu_state.flags & A_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & A_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline int CF_SET() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int CF_SET() +{ +***** + +***** CPU\x86_flags.h + case FLAGS_ADD8: + return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100; + case FLAGS_ADD16: + return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000; + case FLAGS_ADD32: +***** CPU_NEW\X86_FLAGS.H + case FLAGS_ADD8: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; + case FLAGS_ADD16: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; + case FLAGS_ADD32: +***** + +***** CPU\x86_flags.h + + case FLAGS_SUB8: +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + + case FLAGS_SUB8: +***** + +***** CPU\x86_flags.h + + case FLAGS_SHL8: + return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80; + case FLAGS_SHL16: + return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000; + case FLAGS_SHL32: + return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000; + +***** CPU_NEW\X86_FLAGS.H + + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || + (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + + case FLAGS_SHL8: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; + case FLAGS_SHL16: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; + case FLAGS_SHL32: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; + +***** + +***** CPU\x86_flags.h + return 0; + +***** CPU_NEW\X86_FLAGS.H + return 0; + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; + + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 :0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; + +***** + +***** CPU\x86_flags.h + return cpu_state.flags & C_FLAG; + + default: + return 0; + } +} +***** CPU_NEW\X86_FLAGS.H + return cpu_state.flags & C_FLAG; + } + return 0; +} +***** + +***** CPU\x86_flags.h + +static __inline void flags_rebuild() +{ +***** CPU_NEW\X86_FLAGS.H + +//#define ZF_SET() (flags & Z_FLAG) +//#define NF_SET() (flags & N_FLAG) +//#define PF_SET() (flags & P_FLAG) +//#define VF_SET() (flags & V_FLAG) +//#define CF_SET() (flags & C_FLAG) +//#define AF_SET() (flags & A_FLAG) + +static inline void flags_rebuild() +{ +***** + +***** CPU\x86_flags.h + +static __inline void flags_extract() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void flags_extract() +{ +***** + +***** CPU\x86_flags.h + +static __inline void flags_rebuild_c() +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void flags_rebuild_c() +{ +***** + +***** CPU\x86_flags.h + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } +***** CPU_NEW\X86_FLAGS.H + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } +***** + +***** CPU\x86_flags.h + +static __inline void setznp8(uint8_t val) +{ +***** CPU_NEW\X86_FLAGS.H + +static inline int flags_res_valid() +{ + if (cpu_state.flags_op == FLAGS_UNKNOWN || + (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; + + return 1; +} + +static inline void setznp8(uint8_t val) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setznp16(uint16_t val) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setznp16(uint16_t val) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setznp32(uint32_t val) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setznp32(uint32_t val) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setadd8(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H + +#define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ + cpu_state.flags_res = res; + +static inline void setadd8(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd16(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd16(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd32(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd32(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd8nc(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd8nc(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd16nc(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd16nc(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setadd32nc(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setadd32nc(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setsub8(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void setsub8(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub16(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub16(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub32(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub32(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setsub8nc(uint8_t a, uint8_t b) +{ +***** CPU_NEW\X86_FLAGS.H + +static inline void setsub8nc(uint8_t a, uint8_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub16nc(uint16_t a, uint16_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub16nc(uint16_t a, uint16_t b) +{ +***** + +***** CPU\x86_flags.h +} +static __inline void setsub32nc(uint32_t a, uint32_t b) +{ +***** CPU_NEW\X86_FLAGS.H +} +static inline void setsub32nc(uint32_t a, uint32_t b) +{ +***** + +***** CPU\x86_flags.h + +static __inline void setadc8(uint8_t a, uint8_t b) +{ + uint16_t c=(uint16_t)a+(uint16_t)b+tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags&=~0x8D5; + cpu_state.flags|=znptable8[c&0xFF]; + if (c&0x100) cpu_state.flags|=C_FLAG; + if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; + if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; +} +static __inline void setadc16(uint16_t a, uint16_t b) +{ + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags&=~0x8D5; + cpu_state.flags|=znptable16[c&0xFFFF]; + if (c&0x10000) cpu_state.flags|=C_FLAG; + if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; + if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; +} +static __inline void setadc32(uint32_t a, uint32_t b) +{ + uint32_t c=(uint32_t)a+(uint32_t)b+tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags&=~0x8D5; + cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); + cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); + if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; + if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; + if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; +} + +extern void cpu_386_flags_extract(); +***** CPU_NEW\X86_FLAGS.H + +extern void cpu_386_flags_extract(); +***** + diff --git a/src/x86_ops_arith.txt b/src/x86_ops_arith.txt new file mode 100644 index 000000000..f93451d0b --- /dev/null +++ b/src/x86_ops_arith.txt @@ -0,0 +1,11 @@ +Comparing files CPU\x86_ops_arith.h and CPU_NEW\X86_OPS_ARITH.H +***** CPU\x86_ops_arith.h + fetch_ea_16(fetchdat); + src = getlong(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ARITH.H + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); if (cpu_state.abrt) return 1; +***** + diff --git a/src/x86_ops_atomic.txt b/src/x86_ops_atomic.txt new file mode 100644 index 000000000..778fe2d38 --- /dev/null +++ b/src/x86_ops_atomic.txt @@ -0,0 +1,161 @@ +Comparing files CPU\x86_ops_atomic.h and CPU_NEW\X86_OPS_ATOMIC.H +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** + +***** CPU\x86_ops_atomic.h + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** CPU_NEW\X86_OPS_ATOMIC.H + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); +***** + +***** CPU\x86_ops_atomic.h + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** CPU_NEW\X86_OPS_ATOMIC.H + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_atomic.h + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_ATOMIC.H + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); if (cpu_state.abrt) return 1; +***** + diff --git a/src/x86_ops_bcd.txt b/src/x86_ops_bcd.txt new file mode 100644 index 000000000..efbc54429 --- /dev/null +++ b/src/x86_ops_bcd.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_bcd.h and CPU_NEW\X86_OPS_BCD.H +FC: no differences encountered + diff --git a/src/x86_ops_bit.txt b/src/x86_ops_bit.txt new file mode 100644 index 000000000..47d36c9d2 --- /dev/null +++ b/src/x86_ops_bit.txt @@ -0,0 +1,157 @@ +Comparing files CPU\x86_ops_bit.h and CPU_NEW\X86_OPS_BIT.H +***** CPU\x86_ops_bit.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** CPU_NEW\X86_OPS_BIT.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; +***** + +***** CPU\x86_ops_bit.h + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** CPU_NEW\X86_OPS_BIT.H + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteaw(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_bit.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** CPU_NEW\X86_OPS_BIT.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp = geteal(); +***** + +***** CPU\x86_ops_bit.h + default: + x386_dynarec_log("Bad 0F BA opcode %02X\n", rmdat & 0x38); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_BIT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + diff --git a/src/x86_ops_bitscan.txt b/src/x86_ops_bitscan.txt new file mode 100644 index 000000000..a620c7932 --- /dev/null +++ b/src/x86_ops_bitscan.txt @@ -0,0 +1,11 @@ +Comparing files CPU\x86_ops_bitscan.h and CPU_NEW\X86_OPS_BITSCAN.H +***** CPU\x86_ops_bitscan.h + uint32_t temp; + int instr_cycles = 0; + +***** CPU_NEW\X86_OPS_BITSCAN.H + uint32_t temp; + int instr_cycles = 0; + +***** + diff --git a/src/x86_ops_call.txt b/src/x86_ops_call.txt new file mode 100644 index 000000000..0938461ee --- /dev/null +++ b/src/x86_ops_call.txt @@ -0,0 +1,173 @@ +Comparing files CPU\x86_ops_call.h and CPU_NEW\X86_OPS_CALL.H +***** CPU\x86_ops_call.h + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; + \ + cpu_state.pc = new_pc; \ +***** CPU_NEW\X86_OPS_CALL.H + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ +***** + +***** CPU\x86_ops_call.h + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg); \ + else \ +***** CPU_NEW\X86_OPS_CALL.H + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg, old_pc); \ + else \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } \ +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } +***** + +***** CPU\x86_ops_call.h + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; + \ + cpu_state.pc = new_pc; \ +***** CPU_NEW\X86_OPS_CALL.H + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ +***** + +***** CPU\x86_ops_call.h + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg); \ + else \ +***** CPU_NEW\X86_OPS_CALL.H + cgate16 = cgate32 = 0; \ + if (msw & 1) loadcscall(new_seg, old_pc); \ + else \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } \ +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } \ +***** + +***** CPU\x86_ops_call.h + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + } +***** CPU_NEW\X86_OPS_CALL.H + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } + \ + PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ + } +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + +***** CPU\x86_ops_call.h + SEG_CHECK_READ(cpu_state.ea_seg); + oxpc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_CALL.H + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = cpu_state.pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); +***** + +***** CPU\x86_ops_call.h + cpu_state.pc = new_pc; + loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** CPU_NEW\X86_OPS_CALL.H + cpu_state.pc = new_pc; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + CPU_BLOCK_END(); +***** + diff --git a/src/x86_ops_flag.txt b/src/x86_ops_flag.txt new file mode 100644 index 000000000..21220f720 --- /dev/null +++ b/src/x86_ops_flag.txt @@ -0,0 +1,78 @@ +Comparing files CPU\x86_ops_flag.h and CPU_NEW\X86_OPS_FLAG.H +***** CPU\x86_ops_flag.h + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** CPU_NEW\X86_OPS_FLAG.H + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** + +***** CPU\x86_ops_flag.h + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** CPU_NEW\X86_OPS_FLAG.H + { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + +***** CPU\x86_ops_flag.h + { + + ESP = old_esp; +***** CPU_NEW\X86_OPS_FLAG.H + { + ESP = old_esp; +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + +***** CPU\x86_ops_flag.h + +#if 0 + codegen_flags_changed = 0; +#endif + +***** CPU_NEW\X86_OPS_FLAG.H + + codegen_flags_changed = 0; + +***** + diff --git a/src/x86_ops_fpu.txt b/src/x86_ops_fpu.txt new file mode 100644 index 000000000..6002fbaa3 --- /dev/null +++ b/src/x86_ops_fpu.txt @@ -0,0 +1,12 @@ +Comparing files CPU\x86_ops_fpu.h and CPU_NEW\X86_OPS_FPU.H +***** CPU\x86_ops_fpu.h +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +static int opESCAPE_d8_a16(uint32_t fetchdat) +{ +***** CPU_NEW\X86_OPS_FPU.H +static int opESCAPE_d8_a16(uint32_t fetchdat) +{ +***** + diff --git a/src/x86_ops_jump.txt b/src/x86_ops_jump.txt new file mode 100644 index 000000000..53885c038 --- /dev/null +++ b/src/x86_ops_jump.txt @@ -0,0 +1,21 @@ +Comparing files CPU\x86_ops_inc_dec.h and CPU_NEW\X86_OPS_INC_DEC.H +***** CPU\x86_ops_inc_dec.h + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_INC_DEC.H + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) +***** + +***** CPU\x86_ops_inc_dec.h + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_INC_DEC.H + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) +***** + diff --git a/src/x86_ops_misc.txt b/src/x86_ops_misc.txt new file mode 100644 index 000000000..909fbeacb --- /dev/null +++ b/src/x86_ops_misc.txt @@ -0,0 +1,10 @@ +Comparing files CPU\x86_ops_misc.h and CPU_NEW\X86_OPS_MISC.H +***** CPU\x86_ops_misc.h + if(smi_latched) enter_smm(); + CPU_BLOCK_END(); + return 0; +***** CPU_NEW\X86_OPS_MISC.H + if(smi_latched) enter_smm(); + return 0; +***** + diff --git a/src/x86_ops_mmx.txt b/src/x86_ops_mmx.txt new file mode 100644 index 000000000..9543f7eb4 --- /dev/null +++ b/src/x86_ops_mmx.txt @@ -0,0 +1,23 @@ +Comparing files CPU\x86_ops_mmx_pack.h and CPU_NEW\X86_OPS_MMX_PACK.H +***** CPU\x86_ops_mmx_pack.h + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** CPU_NEW\X86_OPS_MMX_PACK.H + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** + +***** CPU\x86_ops_mmx_pack.h + uint32_t src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** CPU_NEW\X86_OPS_MMX_PACK.H + uint32_t src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; +***** + diff --git a/src/x86_ops_mmx_shift.txt b/src/x86_ops_mmx_shift.txt new file mode 100644 index 000000000..5e4b5653c --- /dev/null +++ b/src/x86_ops_mmx_shift.txt @@ -0,0 +1,38 @@ +Comparing files CPU\x86_ops_mmx_shift.h and CPU_NEW\X86_OPS_MMX_SHIFT.H +***** CPU\x86_ops_mmx_shift.h + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ +***** + +***** CPU\x86_ops_mmx_shift.h + default: + x386_dynarec_log("Bad PSxxW (0F 71) instruction %02X\n", op); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mmx_shift.h + default: + x386_dynarec_log("Bad PSxxD (0F 72) instruction %02X\n", op); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mmx_shift.h + default: + x386_dynarec_log("Bad PSxxQ (0F 73) instruction %02X\n", op); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MMX_SHIFT.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + diff --git a/src/x86_ops_mov.txt b/src/x86_ops_mov.txt new file mode 100644 index 000000000..0469bd4f1 --- /dev/null +++ b/src/x86_ops_mov.txt @@ -0,0 +1,15 @@ +Comparing files CPU\x86_ops_mov.h and CPU_NEW\X86_OPS_MOV.H +***** CPU\x86_ops_mov.h + +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#define opCMOV(condition) \ +***** CPU_NEW\X86_OPS_MOV.H + +#define opCMOV(condition) \ +***** + +***** CPU\x86_ops_mov.h +#endif +***** CPU_NEW\X86_OPS_MOV.H +***** + diff --git a/src/x86_ops_mov_ctrl.txt b/src/x86_ops_mov_ctrl.txt new file mode 100644 index 000000000..54ba5dd2e --- /dev/null +++ b/src/x86_ops_mov_ctrl.txt @@ -0,0 +1,163 @@ +Comparing files CPU\x86_ops_mov_ctrl.h and CPU_NEW\X86_OPS_MOV_CTRL.H +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from CRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from CRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad read of CR%i %i\n",rmdat&7,cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load CRx\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_mov_ctrl.h + cpu_cache_int_enabled = 1; + else if (isibmcpu) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + cpu_cache_int_enabled = 1; + else if (isibmcpu) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad load CR%i\n", cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load CRx\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_mov_ctrl.h + default: + x386_dynarec_log("Bad load CR%i\n", cpu_reg); + cpu_state.pc = cpu_state.oldpc; +***** CPU_NEW\X86_OPS_MOV_CTRL.H + default: + cpu_state.pc = cpu_state.oldpc; +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load DRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load from TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_mov_ctrl.h + { + x386_dynarec_log("Can't load TRx\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_MOV_CTRL.H + { + x86gpf(NULL, 0); +***** + diff --git a/src/x86_ops_mov_seg.txt b/src/x86_ops_mov_seg.txt new file mode 100644 index 000000000..494e02515 --- /dev/null +++ b/src/x86_ops_mov_seg.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_mov_seg.h and CPU_NEW\X86_OPS_MOV_SEG.H +FC: no differences encountered + diff --git a/src/x86_ops_movx.txt b/src/x86_ops_movx.txt new file mode 100644 index 000000000..e102dae1e --- /dev/null +++ b/src/x86_ops_movx.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_movx.h and CPU_NEW\X86_OPS_MOVX.H +FC: no differences encountered + diff --git a/src/x86_ops_msr.txt b/src/x86_ops_msr.txt new file mode 100644 index 000000000..12e9c0005 --- /dev/null +++ b/src/x86_ops_msr.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_msr.h and CPU_NEW\X86_OPS_MSR.H +FC: no differences encountered + diff --git a/src/x86_ops_mul.txt b/src/x86_ops_mul.txt new file mode 100644 index 000000000..9b548257d --- /dev/null +++ b/src/x86_ops_mul.txt @@ -0,0 +1,121 @@ +Comparing files CPU\x86_ops_mul.h and CPU_NEW\X86_OPS_MUL.H +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + SEG_CHECK_READ(cpu_state.ea_seg); + + tempw = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** + +***** CPU\x86_ops_mul.h + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** CPU_NEW\X86_OPS_MUL.H + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); +***** + diff --git a/src/x86_ops_pmode.txt b/src/x86_ops_pmode.txt new file mode 100644 index 000000000..046806f1f --- /dev/null +++ b/src/x86_ops_pmode.txt @@ -0,0 +1,206 @@ +Comparing files CPU\x86_ops_pmode.h and CPU_NEW\X86_OPS_PMODE.H +***** CPU\x86_ops_pmode.h + fetch_ea_16(fetchdat); + /* x386_dynarec_log("ARPL_a16\n"); */ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_PMODE.H + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_pmode.h + fetch_ea_32(fetchdat); + /* x386_dynarec_log("ARPL_a32\n"); */ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_PMODE.H + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_pmode.h + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** CPU_NEW\X86_OPS_PMODE.H + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** + +***** CPU\x86_ops_pmode.h + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); + \ + \ +***** CPU_NEW\X86_OPS_PMODE.H + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ +***** + +***** CPU\x86_ops_pmode.h + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** CPU_NEW\X86_OPS_PMODE.H + int valid; \ + uint16_t sel, desc = 0; \ + \ +***** + +***** CPU\x86_ops_pmode.h + + /* x386_dynarec_log("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ + switch (rmdat & 0x38) +***** CPU_NEW\X86_OPS_PMODE.H + + switch (rmdat & 0x38) +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LLDT!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LTR!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + default: + x386_dynarec_log("Bad 0F 00 opcode %02X\n", rmdat & 0x38); + cpu_state.pc -= 3; +***** CPU_NEW\X86_OPS_PMODE.H + default: + cpu_state.pc -= 3; +***** + +***** CPU\x86_ops_pmode.h + uint16_t limit, tempw; + /* x386_dynarec_log("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ + switch (rmdat & 0x38) +***** CPU_NEW\X86_OPS_PMODE.H + uint16_t limit, tempw; + switch (rmdat & 0x38) +***** + +***** CPU\x86_ops_pmode.h + seteaw(gdt.limit); + base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */ + if (is286) +***** CPU_NEW\X86_OPS_PMODE.H + seteaw(gdt.limit); + base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); + if (is286) +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LGDT!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + } + /* x386_dynarec_log("LGDT %08X:%08X\n", easeg, eaaddr); */ + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_PMODE.H + } + if (cpu_mod != 3) +***** + +***** CPU\x86_ops_pmode.h + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + /* x386_dynarec_log(" %08X %04X\n", base, limit); */ + gdt.limit = limit; +***** CPU_NEW\X86_OPS_PMODE.H + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + gdt.limit = limit; +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid LIDT!\n"); + x86gpf(NULL,0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL,0); +***** + +***** CPU\x86_ops_pmode.h + } + /* x386_dynarec_log("LIDT %08X:%08X\n", easeg, eaaddr); */ + if (cpu_mod != 3) +***** CPU_NEW\X86_OPS_PMODE.H + } + if (cpu_mod != 3) +***** + +***** CPU\x86_ops_pmode.h + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + /* x386_dynarec_log(" %08X %04X\n", base, limit); */ + idt.limit = limit; +***** CPU_NEW\X86_OPS_PMODE.H + base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; + idt.limit = limit; +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("LMSW - ring not zero!\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_pmode.h + { + x386_dynarec_log("Invalid INVLPG!\n"); + x86gpf(NULL, 0); +***** CPU_NEW\X86_OPS_PMODE.H + { + x86gpf(NULL, 0); +***** + +***** CPU\x86_ops_pmode.h + } + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); +***** CPU_NEW\X86_OPS_PMODE.H + } + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); +***** + +***** CPU\x86_ops_pmode.h + default: + x386_dynarec_log("Bad 0F 01 opcode %02X\n", rmdat & 0x38); + cpu_state.pc -= 3; +***** CPU_NEW\X86_OPS_PMODE.H + default: + cpu_state.pc -= 3; +***** + diff --git a/src/x86_ops_prefix.txt b/src/x86_ops_prefix.txt new file mode 100644 index 000000000..7e4233269 --- /dev/null +++ b/src/x86_ops_prefix.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_prefix.h and CPU_NEW\X86_OPS_PREFIX.H +FC: no differences encountered + diff --git a/src/x86_ops_rep.txt b/src/x86_ops_rep.txt new file mode 100644 index 000000000..e08f17803 --- /dev/null +++ b/src/x86_ops_rep.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_rep.h and CPU_NEW\X86_OPS_REP.H +FC: no differences encountered + diff --git a/src/x86_ops_ret.txt b/src/x86_ops_ret.txt new file mode 100644 index 000000000..a04382278 --- /dev/null +++ b/src/x86_ops_ret.txt @@ -0,0 +1,66 @@ +Comparing files CPU\x86_ops_ret.h and CPU_NEW\X86_OPS_RET.H +***** CPU\x86_ops_ret.h +#define RETF_a16(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** CPU_NEW\X86_OPS_RET.H +#define RETF_a16(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** + +***** CPU\x86_ops_ret.h + } \ + oxpc = cpu_state.pc; \ + if (stack32) \ +***** CPU_NEW\X86_OPS_RET.H + } \ + if (stack32) \ +***** + +***** CPU\x86_ops_ret.h +#define RETF_a32(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** CPU_NEW\X86_OPS_RET.H +#define RETF_a32(stack_offset) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ + { \ +***** + +***** CPU\x86_ops_ret.h + } \ + oxpc = cpu_state.pc; \ + if (stack32) \ +***** CPU_NEW\X86_OPS_RET.H + } \ + if (stack32) \ +***** + +***** CPU\x86_ops_ret.h + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) +***** CPU_NEW\X86_OPS_RET.H + uint16_t new_cs; + if (stack32) +***** + +***** CPU\x86_ops_ret.h + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) +***** CPU_NEW\X86_OPS_RET.H + uint16_t new_cs; + if (stack32) +***** + +***** CPU\x86_ops_ret.h + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) +***** CPU_NEW\X86_OPS_RET.H + uint16_t new_cs; + if (stack32) +***** + diff --git a/src/x86_ops_set.txt b/src/x86_ops_set.txt new file mode 100644 index 000000000..be3a1a7ea --- /dev/null +++ b/src/x86_ops_set.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x86_ops_set.h and CPU_NEW\X86_OPS_SET.H +FC: no differences encountered + diff --git a/src/x86_ops_shift.txt b/src/x86_ops_shift.txt new file mode 100644 index 000000000..670c26b78 --- /dev/null +++ b/src/x86_ops_shift.txt @@ -0,0 +1,126 @@ +Comparing files CPU\x86_ops_shift.h and CPU_NEW\X86_OPS_SHIFT.H +***** CPU\x86_ops_shift.h + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; + \ + case 0x10: /*RCL b,CL*/ \ +***** CPU_NEW\X86_OPS_SHIFT.H + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ +***** + +***** CPU\x86_ops_shift.h + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** CPU_NEW\X86_OPS_SHIFT.H + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ +***** + +***** CPU\x86_ops_shift.h + count = getbyte() & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = getbyte() & 31; \ + operation(); \ + \ +***** + +***** CPU\x86_ops_shift.h + count = CL & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = CL & 31; \ + operation(); \ + \ +***** + +***** CPU\x86_ops_shift.h + count = getbyte() & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = getbyte() & 31; \ + operation(); \ + \ +***** + +***** CPU\x86_ops_shift.h + count = CL & 31; \ + operation() \ + \ +***** CPU_NEW\X86_OPS_SHIFT.H + count = CL & 31; \ + operation(); \ + \ +***** + diff --git a/src/x86_ops_stack.txt b/src/x86_ops_stack.txt new file mode 100644 index 000000000..4c3cdabc2 --- /dev/null +++ b/src/x86_ops_stack.txt @@ -0,0 +1,65 @@ +Comparing files CPU\x86_ops_stack.h and CPU_NEW\X86_OPS_STACK.H +***** CPU\x86_ops_stack.h + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); +***** CPU_NEW\X86_OPS_STACK.H + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); +***** + +***** CPU\x86_ops_stack.h + +PUSH_SEG_OPS(CS) +PUSH_SEG_OPS(DS) +PUSH_SEG_OPS(ES) +PUSH_SEG_OPS(FS) +PUSH_SEG_OPS(GS) +PUSH_SEG_OPS(SS) + +POP_SEG_OPS(DS, &cpu_state.seg_ds) +POP_SEG_OPS(ES, &cpu_state.seg_es) +POP_SEG_OPS(FS, &cpu_state.seg_fs) +POP_SEG_OPS(GS, &cpu_state.seg_gs) + +***** CPU_NEW\X86_OPS_STACK.H + +PUSH_SEG_OPS(CS); +PUSH_SEG_OPS(DS); +PUSH_SEG_OPS(ES); +PUSH_SEG_OPS(FS); +PUSH_SEG_OPS(GS); +PUSH_SEG_OPS(SS); + +POP_SEG_OPS(DS, &cpu_state.seg_ds); +POP_SEG_OPS(ES, &cpu_state.seg_es); +POP_SEG_OPS(FS, &cpu_state.seg_fs); +POP_SEG_OPS(GS, &cpu_state.seg_gs); + +***** + +***** CPU\x86_ops_stack.h + temp_seg = POP_W(); if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** CPU_NEW\X86_OPS_STACK.H + temp_seg = POP_W(); if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** + +***** CPU\x86_ops_stack.h + temp_seg = POP_L(); if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** CPU_NEW\X86_OPS_STACK.H + temp_seg = POP_L(); if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + CLOCK_CYCLES(is486 ? 3 : 7); +***** + diff --git a/src/x86_ops_string.txt b/src/x86_ops_string.txt new file mode 100644 index 000000000..d8360e622 --- /dev/null +++ b/src/x86_ops_string.txt @@ -0,0 +1,553 @@ +Comparing files CPU\x86_ops_string.h and CPU_NEW\X86_OPS_STRING.H +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } + CLOCK_CYCLES((is486) ? 8 : 10); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, DI, AL); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, DI, AL); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, EDI, AL); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, EDI, AL); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, DI, AX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, DI, AX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, EDI, AX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, EDI, AX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, DI, EAX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, DI, EAX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; +***** CPU_NEW\X86_OPS_STRING.H +{ + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(4); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(4); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + CLOCK_CYCLES(5); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + CLOCK_CYCLES(5); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(7); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(7); +***** + +***** CPU\x86_ops_string.h + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI--; + else DI++; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint8_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint16_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** CPU_NEW\X86_OPS_STRING.H + uint32_t temp; + + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(15); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; + CLOCK_CYCLES(15); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + outb(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI--; + else SI++; + outb(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + outb(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; + outb(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + outw(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; + outw(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + outw(DX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; + outw(DX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + outl(EDX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; + outl(EDX, temp); +***** + +***** CPU\x86_ops_string.h + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + outl(EDX, temp); +***** CPU_NEW\X86_OPS_STRING.H + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; + outl(EDX, temp); +***** + diff --git a/src/x86_ops_xchg.txt b/src/x86_ops_xchg.txt new file mode 100644 index 000000000..c290e1b1c --- /dev/null +++ b/src/x86_ops_xchg.txt @@ -0,0 +1,55 @@ +Comparing files CPU\x86_ops_xchg.h and CPU_NEW\X86_OPS_XCHG.H +***** CPU\x86_ops_xchg.h + uint8_t temp; + fetch_ea_16(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint8_t temp; + + fetch_ea_16(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint8_t temp; + fetch_ea_32(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint8_t temp; + + fetch_ea_32(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint16_t temp; + fetch_ea_16(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint16_t temp; + + fetch_ea_16(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint16_t temp; + fetch_ea_32(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint16_t temp; + + fetch_ea_32(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint32_t temp; + fetch_ea_16(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint32_t temp; + + fetch_ea_16(fetchdat); +***** + +***** CPU\x86_ops_xchg.h + uint32_t temp; + fetch_ea_32(fetchdat); +***** CPU_NEW\X86_OPS_XCHG.H + uint32_t temp; + + fetch_ea_32(fetchdat); +***** + diff --git a/src/x86_seg.txt b/src/x86_seg.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/x86seg.d b/src/x86seg.d new file mode 100644 index 000000000..4c74c8328 --- /dev/null +++ b/src/x86seg.d @@ -0,0 +1,3 @@ +x86seg.o: cpu/x86seg.c 86box.h cpu_common/cpu.h device.h timer.h \ + machine/machine.h mem.h nvr.h cpu_common/x86.h cpu/x86_flags.h \ + cpu_common/386_common.h diff --git a/src/x86seg.txt b/src/x86seg.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/x87.d b/src/x87.d new file mode 100644 index 000000000..05e2a99d1 --- /dev/null +++ b/src/x87.d @@ -0,0 +1,3 @@ +x87.o: cpu_common/x87.c 86box.h cpu_common/cpu.h mem.h pic.h \ + cpu_common/x86.h cpu/x86_flags.h cpu_common/x86_ops.h cpu_common/x87.h \ + cpu_common/386_common.h diff --git a/src/x87.txt b/src/x87.txt new file mode 100644 index 000000000..a446f0813 --- /dev/null +++ b/src/x87.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x87.c and CPU_NEW\X87.C +FC: no differences encountered + diff --git a/src/x87_bak/x87.h b/src/x87_bak/x87.h new file mode 100644 index 000000000..be30c280c --- /dev/null +++ b/src/x87_bak/x87.h @@ -0,0 +1,58 @@ +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + +uint32_t x87_pc_off,x87_op_off; +uint16_t x87_pc_seg,x87_op_seg; + +static inline void x87_set_mmx() +{ +#ifdef USE_NEW_DYNAREC + cpu_state.TOP = 0; + *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; + cpu_state.ismmx = 1; +#else + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 1; +#endif +} + +static inline void x87_emms() +{ +#ifdef USE_NEW_DYNAREC + *(uint64_t *)cpu_state.tag = 0; + cpu_state.ismmx = 0; +#else + uint64_t *p; + p = (uint64_t *)cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; +#endif +} + + +uint16_t x87_gettag(); +void x87_settag(uint16_t new_tag); + +#ifdef USE_NEW_DYNAREC +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 7) + +#define X87_ROUNDING_NEAREST 0 +#define X87_ROUNDING_DOWN 1 +#define X87_ROUNDING_UP 2 +#define X87_ROUNDING_CHOP 3 + +void codegen_set_rounding_mode(int mode); +#else +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) +/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ +#define TAG_UINT64 (1 << 2) +#endif diff --git a/src/x87_bak/x87_ops.h b/src/x87_bak/x87_ops.h new file mode 100644 index 000000000..57416251f --- /dev/null +++ b/src/x87_bak/x87_ops.h @@ -0,0 +1,2147 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops.h 1.0.8 2019/06/11 + * + * Authors: Fred N. van Kempen, + * Sarah Walker, + * leilei, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 leilei. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 Fred N. van Kempen. + */ +#include +#include +#ifdef _MSC_VER +# include +#endif +// #include "x87_timings.h" + +#ifdef ENABLE_FPU_LOG +extern void fpu_log(const char *fmt, ...); +#else +#ifndef fpu_log +#define fpu_log(fmt, ...) +#endif +#endif + +static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}; + +#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] + +#define STATUS_ZERODIVIDE 4 + +#ifdef FPU_8087 +#define x87_div(dst, src1, src2) do \ + { \ + if (((double)src2) == 0.0) \ + { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double)src2; \ + else \ + { \ + fpu_log("FPU : divide by zero\n"); \ + if (!(cpu_state.npxc & 0x80)) { \ + cpu_state.npxs |= 0x80; \ + nmi = 1; \ + } \ + return 1; \ + } \ + } \ + else \ + dst = src1 / (double)src2; \ + } while (0) +#else +#define x87_div(dst, src1, src2) do \ + { \ + if (((double)src2) == 0.0) \ + { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double)src2; \ + else \ + { \ + fpu_log("FPU : divide by zero\n"); \ + picint(1 << 13); \ + return 1; \ + } \ + } \ + else \ + dst = src1 / (double)src2; \ + } while (0) +#endif + +static __inline void x87_checkexceptions() +{ +} + +static __inline void x87_push(double i) +{ +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else + cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.ST[cpu_state.TOP] = i; + cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; +#endif +} + +static __inline void x87_push_u64(uint64_t i) +{ + union + { + double d; + uint64_t ll; + } td; + + td.ll = i; + +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#else + cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.ST[cpu_state.TOP] = td.d; + cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; +#endif +} + +static __inline double x87_pop() +{ +#ifdef USE_NEW_DYNAREC + double t = cpu_state.ST[cpu_state.TOP&7]; + cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + cpu_state.TOP++; + return t; +#else + double t = cpu_state.ST[cpu_state.TOP]; + cpu_state.tag[cpu_state.TOP&7] = 3; + cpu_state.TOP=(cpu_state.TOP+1)&7; + return t; +#endif +} + +static int old_round = FE_TONEAREST; + +static __inline int64_t x87_round_save(void) +{ + old_round = fetgetround(); +} + +static __inline int64_t x87_round_set(void) +{ + old_round = fetgetround(); + + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + fesetround(FE_TONEAREST); + break; + case 1: /*Down*/ + fesetround(FE_DOWNWARD); + break; + case 2: /*Up*/ + fesetround(FE_UPWARD); + break; + case 3: /*Chop*/ + fesetround(FE_TOWARDZERO); + break; + } +} + +static __inline int64_t x87_round_restore(void) +{ + fesetround(old_round); +} + +#ifdef PCEM_CODE +static __inline int64_t x87_fround(double b) +{ +#ifdef PCEM_CODE + int64_t a, c; +#endif + + switch ((cpu_state.npxc >> 10) & 3) + { + case 0: /*Nearest*/ +#ifdef PCEM_CODE + a = (int64_t)floor(b); + c = (int64_t)floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; +#else + return (int64_t)round(b); +#endif + case 1: /*Down*/ + return (int64_t)floor(b); + case 2: /*Up*/ + return (int64_t)ceil(b); + case 3: /*Chop*/ +#ifdef PCEM_CODE + return (int64_t)b; +#else + return (int64_t)trunc(b); +#endif + } + + return 0; +} +#else +static __inline int64_t x87_fround(double b) +{ + int64_t ret; + + x87_round_set(); + ret = (int64_t) rint(b); + x87_round_restore(); +} +#endif +#define BIAS80 16383 +#define BIAS64 1023 + +static __inline double x87_ld80() +{ + int64_t exp64; + int64_t blah; + int64_t exp64final; + int64_t mant64; + int64_t sign; + + struct { + int16_t begin; + union + { + double d; + uint64_t ll; + } eind; + } test; + + test.eind.ll = readmeml(easeg,cpu_state.eaaddr); + test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; + test.begin = readmemw(easeg,cpu_state.eaaddr+8); + + exp64 = (((test.begin&0x7fff) - BIAS80)); + blah = ((exp64 >0)?exp64:-exp64)&0x3ff; + exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + + mant64 = (test.eind.ll >> 11) & (0xfffffffffffffll); + sign = (test.begin&0x8000)?1:0; + + if ((test.begin & 0x7fff) == 0x7fff) + exp64final = 0x7ff; + if ((test.begin & 0x7fff) == 0) + exp64final = 0; + if (test.eind.ll & 0x400) + mant64++; + + test.eind.ll = (sign <<63)|(exp64final << 52)| mant64; + + return test.eind.d; +} + +static __inline void x87_st80(double d) +{ + int64_t sign80; + int64_t exp80; + int64_t exp80final; + int64_t mant80; + int64_t mant80final; + + struct { + int16_t begin; + union + { + double d; + uint64_t ll; + } eind; + } test; + + test.eind.d=d; + + sign80 = (test.eind.ll&(0x8000000000000000ll))?1:0; + exp80 = test.eind.ll&(0x7ff0000000000000ll); + exp80final = (exp80>>52); + mant80 = test.eind.ll&(0x000fffffffffffffll); + mant80final = (mant80 << 11); + + if (exp80final == 0x7ff) /*Infinity / Nan*/ + { + exp80final = 0x7fff; + mant80final |= (0x8000000000000000ll); + } + else if (d != 0){ /* Zero is a special case */ + /* Elvira wants the 8 and tcalc doesn't */ + mant80final |= (0x8000000000000000ll); + /* Ca-cyber doesn't like this when result is zero. */ + exp80final += (BIAS80 - BIAS64); + } + test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; + test.eind.ll = mant80final; + + writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff); + writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32); + writememw(easeg,cpu_state.eaaddr+8,test.begin); +} + +static __inline void x87_st_fsave(int reg) +{ + reg = (cpu_state.TOP + reg) & 7; + + if (cpu_state.tag[reg] & TAG_UINT64) + { + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); + writememw(easeg, cpu_state.eaaddr + 8, 0x5555); + } + else + x87_st80(cpu_state.ST[reg]); +} + +static __inline void x87_ld_frstor(int reg) +{ + reg = (cpu_state.TOP + reg) & 7; + + cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); + cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); + +#ifdef USE_NEW_DYNAREC + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + { + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } + else + { + cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.ST[reg] = x87_ld80(); + } +#else + if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) + { + cpu_state.tag[reg] = TAG_UINT64; + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } + else + cpu_state.ST[reg] = x87_ld80(); +#endif +} + +static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) +{ + r->l[0] = readmeml(easeg, cpu_state.eaaddr); + r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + *w4 = readmemw(easeg, cpu_state.eaaddr + 8); +} + +static __inline void x87_stmmx(MMX_REG r) +{ + writememl(easeg, cpu_state.eaaddr, r.l[0]); + writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); + writememw(easeg, cpu_state.eaaddr + 8, 0xffff); +} + +#include + +static __inline uint16_t x87_compare(double a, double b) +{ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 + uint32_t result; + double ea = a, eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ull; + const uint64_t ib = 0x3fec1a6ff866a938ull; + + /* Hack to make CHKCOP happy. */ + if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) + return C3; + + if (!is386 && !(cpu_state.npxc & 0x1000) && + ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; + +#ifndef _MSC_VER + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile ("" : : : "memory"); + + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m" (result) + : "m" (ea), "m" (eb) + ); +#else + _ReadWriteBarrier(); + _asm + { + fld eb + fld ea + fclex + fcompp + fnstsw result + } +#endif + + return result & (C0|C2|C3); +#else + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + double ea = a, eb = b; + + if (!is386 && !(cpu_state.npxc & 0x1000) && + ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; + + if (ea == eb) + result |= C3; + else if (ea < eb) + result |= C0; + + return result; +#endif +} + +static __inline uint16_t x87_ucompare(double a, double b) +{ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ + uint32_t result; + +#ifndef _MSC_VER + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + asm volatile ("" : : : "memory"); + + asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fucompp\n" + "fnstsw %0\n" + : "=m" (result) + : "m" (a), "m" (b) + ); +#else + _ReadWriteBarrier(); + _asm + { + fld b + fld a + fclex + fcompp + fnstsw result + } +#endif + + return result & (C0|C2|C3); +#else + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + + if (a == b) + result |= C3; + else if (a < b) + result |= C0; + + return result; +#endif +} + +typedef union +{ + float s; + uint32_t i; +} x87_ts; + +typedef union +{ + double d; + uint64_t i; +} x87_td; + +#ifdef FPU_8087 +#define FP_ENTER() { \ + fpucount++; \ + } +#else +#define FP_ENTER() do \ + { \ + if (cr0 & 0xc) \ + { \ + x86_int(7); \ + return 1; \ + } \ + fpucount++; \ + } while (0) +#endif + +// #ifdef USE_NEW_DYNAREC +#if 1 +#define FP_TAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP&7].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP&7].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; +#ifdef USE_NEW_DYNAREC +#define FP_NNPXC() codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); +#else +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#endif +#define FP_TOP(x) (x & 7) +#define FP_DTAG 0ULL +#define FP_CTAG 0x0101010101010101ull +#define FP_EMPTY TAG_EMPTY +#ifdef USE_NEW_DYNAREC +#define FP_RNPXC() codegen_set_rounding_mode(X87_ROUNDING_NEAREST); +#else +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#endif +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; +#define FP_DECTOP() cpu_state.TOP--; +#define FP_INCTOP() cpu_state.TOP++; +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#define FP_686 +#endif +#else +#define FP_TAG() cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; +#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; +#define FP_LSTAG() cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +#define FP_LSQ() cpu_state.MM[cpu_state.TOP].q = temp64; +#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP].q; +#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; +#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); +#define FP_TOP(x) (x) +#define FP_DTAG 0x0303030303030303ll +#define FP_CTAG 0ULL +#define FP_EMPTY 3 +#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); +#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = 1; +#define FP_DECTOP() cpu_state.TOP = (cpu_state.TOP - 1) & 7 +#define FP_INCTOP() cpu_state.TOP = (cpu_state.TOP + 1) & 7 +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#define FP_686 +#endif +#endif + +#include "x87_ops_arith.h" +#include "x87_ops_misc.h" +#include "x87_ops_loadstore.h" + +#ifndef FPU_8087 +static int op_nofpu_a16(uint32_t fetchdat) +{ + if (cr0 & 0xc) + { + x86_int(7); + return 1; + } + else + { + fetch_ea_16(fetchdat); + return 0; + } +} +static int op_nofpu_a32(uint32_t fetchdat) +{ + if (cr0 & 0xc) + { + x86_int(7); + return 1; + } + else + { + fetch_ea_32(fetchdat); + return 0; + } +} +#endif + +#ifdef FPU_8087 +static int FPU_ILLEGAL_a16(uint32_t fetchdat) +{ + geteaw(); + wait(timing_rr, 0); + return 0; +} +#else +static int FPU_ILLEGAL_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); + return 0; +} + +static int FPU_ILLEGAL_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); + return 0; +} +#endif + +#define ILLEGAL_a16 FPU_ILLEGAL_a16 + +#ifdef FPU_8087 +const OpFn OP_TABLE(fpu_8087_d8)[32] = +{ + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +}; + +const OpFn OP_TABLE(fpu_8087_d9)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 +}; + +const OpFn OP_TABLE(fpu_8087_da)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; + +const OpFn OP_TABLE(fpu_8087_db)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFI, opFI, opFCLEX, opFINIT, ILLEGAL_a16, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; + +const OpFn OP_TABLE(fpu_8087_dc)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + +const OpFn OP_TABLE(fpu_8087_dd)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; + +const OpFn OP_TABLE(fpu_8087_de)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_8087_df)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +#else +#define ILLEGAL_a32 FPU_ILLEGAL_a32 + +const OpFn OP_TABLE(fpu_d8_a16)[32] = +{ + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, + opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +}; +const OpFn OP_TABLE(fpu_d8_a32)[32] = +{ + opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, + opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, + opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, + opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +}; + +const OpFn OP_TABLE(fpu_287_d9_a16)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_287_d9_a32)[256] = +{ + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_d9_a16)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_d9_a32)[256] = +{ + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +const OpFn OP_TABLE(fpu_287_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +const OpFn OP_TABLE(fpu_686_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, + opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, + opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, + opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_686_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, opFCMOVB, + opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, + opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, + opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; +#endif + +const OpFn OP_TABLE(fpu_287_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +const OpFn OP_TABLE(fpu_686_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, + opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, + opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, + opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_686_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, + opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, + opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, + opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; +#endif + +const OpFn OP_TABLE(fpu_287_dc_a16)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; +const OpFn OP_TABLE(fpu_287_dc_a32)[32] = +{ + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + +const OpFn OP_TABLE(fpu_dc_a16)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; +const OpFn OP_TABLE(fpu_dc_a32)[32] = +{ + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + +const OpFn OP_TABLE(fpu_287_dd_a16)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_dd_a32)[256] = +{ + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_dd_a16)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, + opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_dd_a32)[256] = +{ + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, + opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_287_de_a16)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_287_de_a32)[256] = +{ + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_de_a16)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_de_a32)[256] = +{ + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, + ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +const OpFn OP_TABLE(fpu_287_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_287_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +const OpFn OP_TABLE(fpu_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; + +#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +const OpFn OP_TABLE(fpu_686_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +}; +const OpFn OP_TABLE(fpu_686_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +}; +#endif + +const OpFn OP_TABLE(nofpu_a16)[256] = +{ + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, +}; +const OpFn OP_TABLE(nofpu_a32)[256] = +{ + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, +}; +#endif + +#undef ILLEGAL diff --git a/src/cpu/x87_ops_arith.h b/src/x87_bak/x87_ops_arith.h similarity index 88% rename from src/cpu/x87_ops_arith.h rename to src/x87_bak/x87_ops_arith.h index 720a5c469..133ecb689 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/x87_bak/x87_ops_arith.h @@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ ST(0) += use_var; \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(11); \ return 0; \ } \ @@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + FP_TAG(); \ CLOCK_CYCLES(8); \ return 0; \ } @@ -128,7 +128,7 @@ static int opFADD(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) + ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(8); return 0; } @@ -137,7 +137,7 @@ static int opFADDr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(8); return 0; } @@ -146,7 +146,7 @@ static int opFADDP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(8); return 0; @@ -205,7 +205,7 @@ static int opFUCOMPP(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#ifdef FP_686 static int opFCOMI(uint32_t fetchdat) { FP_ENTER(); @@ -237,7 +237,7 @@ static int opFDIV(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(0), ST(0), ST(fetchdat & 7)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(73); return 0; } @@ -246,7 +246,7 @@ static int opFDIVr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(73); return 0; } @@ -255,7 +255,7 @@ static int opFDIVP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(73); return 0; @@ -266,7 +266,7 @@ static int opFDIVR(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(0), ST(fetchdat&7), ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(73); return 0; } @@ -275,7 +275,7 @@ static int opFDIVRr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(73); return 0; } @@ -284,7 +284,7 @@ static int opFDIVRP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(73); return 0; @@ -295,7 +295,7 @@ static int opFMUL(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(16); return 0; } @@ -304,7 +304,7 @@ static int opFMULr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(16); return 0; } @@ -313,7 +313,7 @@ static int opFMULP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(16); return 0; @@ -324,7 +324,7 @@ static int opFSUB(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(8); return 0; } @@ -333,7 +333,7 @@ static int opFSUBr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(8); return 0; } @@ -342,7 +342,7 @@ static int opFSUBP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(8); return 0; @@ -353,7 +353,7 @@ static int opFSUBR(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + FP_TAG(); CLOCK_CYCLES(8); return 0; } @@ -362,7 +362,7 @@ static int opFSUBRr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); CLOCK_CYCLES(8); return 0; } @@ -371,7 +371,7 @@ static int opFSUBRP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + FP_FTAG(); x87_pop(); CLOCK_CYCLES(8); return 0; @@ -399,7 +399,7 @@ static int opFUCOMP(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) +#ifdef FP_686 static int opFUCOMI(uint32_t fetchdat) { FP_ENTER(); diff --git a/src/x87_bak/x87_ops_loadstore.h b/src/x87_bak/x87_ops_loadstore.h new file mode 100644 index 000000000..b5ad491f9 --- /dev/null +++ b/src/x87_bak/x87_ops_loadstore.h @@ -0,0 +1,492 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ + +static int opFILDiw_a16(uint32_t fetchdat) +{ + int16_t temp; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; + x87_push((double)temp); + CLOCK_CYCLES(13); + return 0; +} +#ifndef FPU_8087 +static int opFILDiw_a32(uint32_t fetchdat) +{ + int16_t temp; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; + x87_push((double)temp); + CLOCK_CYCLES(13); + return 0; +} +#endif + +static int opFISTiw_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); + CLOCK_CYCLES(29); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFISTiw_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); + CLOCK_CYCLES(29); + return cpu_state.abrt; +} +#endif + +static int opFISTPiw_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#ifndef FPU_8087 +static int opFISTPiw_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#endif + +static int opFILDiq_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; + x87_push((double)temp64); + FP_LSQ(); + FP_LSTAG(); + + CLOCK_CYCLES(10); + return 0; +} +#ifndef FPU_8087 +static int opFILDiq_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; + x87_push((double)temp64); + FP_LSQ(); + FP_LSTAG(); + + CLOCK_CYCLES(10); + return 0; +} +#endif + +static int FBSTP_a16(uint32_t fetchdat) +{ + double tempd; + int c; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) + { + uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t)floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; + x87_pop(); + return 0; +} +#ifndef FPU_8087 +static int FBSTP_a32(uint32_t fetchdat) +{ + double tempd; + int c; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) + { + uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t)floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; + x87_pop(); + return 0; +} +#endif + +static int FISTPiq_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + FP_LSRETQ() + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#ifndef FPU_8087 +static int FISTPiq_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + FP_LSRETQ() + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(29); + return 0; +} +#endif + +static int opFILDil_a16(uint32_t fetchdat) +{ + int32_t templ; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)templ); + CLOCK_CYCLES(9); + return 0; +} +#ifndef FPU_8087 +static int opFILDil_a32(uint32_t fetchdat) +{ + int32_t templ; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)templ); + CLOCK_CYCLES(9); + return 0; +} +#endif + +static int opFISTil_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); + CLOCK_CYCLES(28); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFISTil_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); + CLOCK_CYCLES(28); + return cpu_state.abrt; +} +#endif + +static int opFISTPil_a16(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(28); + return 0; +} +#ifndef FPU_8087 +static int opFISTPil_a32(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(28); + return 0; +} +#endif + +static int opFLDe_a16(uint32_t fetchdat) +{ + double t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; + x87_push(t); + CLOCK_CYCLES(6); + return 0; +} +#ifndef FPU_8087 +static int opFLDe_a32(uint32_t fetchdat) +{ + double t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; + x87_push(t); + CLOCK_CYCLES(6); + return 0; +} +#endif + +static int opFSTPe_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(6); + return 0; +} +#ifndef FPU_8087 +static int opFSTPe_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(6); + return 0; +} +#endif + +static int opFLDd_a16(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; + x87_push(t.d); + CLOCK_CYCLES(3); + return 0; +} +#ifndef FPU_8087 +static int opFLDd_a32(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; + x87_push(t.d); + CLOCK_CYCLES(3); + return 0; +} +#endif + +static int opFSTd_a16(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES(8); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTd_a32(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES(8); + return cpu_state.abrt; +} +#endif + +static int opFSTPd_a16(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} +#ifndef FPU_8087 +static int opFSTPd_a32(uint32_t fetchdat) +{ + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(8); + return 0; +} +#endif + +static int opFLDs_a16(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)ts.s); + CLOCK_CYCLES(3); + return 0; +} +#ifndef FPU_8087 +static int opFLDs_a32(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; + x87_push((double)ts.s); + CLOCK_CYCLES(3); + return 0; +} +#endif + +static int opFSTs_a16(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); + CLOCK_CYCLES(7); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTs_a32(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); + CLOCK_CYCLES(7); + return cpu_state.abrt; +} +#endif + +static int opFSTPs_a16(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(7); + return 0; +} +#ifndef FPU_8087 +static int opFSTPs_a32(uint32_t fetchdat) +{ + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float)ST(0); + seteal(ts.i); if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(7); + return 0; +} +#endif diff --git a/src/x87_bak/x87_ops_misc.h b/src/x87_bak/x87_ops_misc.h new file mode 100644 index 000000000..406c6c86d --- /dev/null +++ b/src/x87_bak/x87_ops_misc.h @@ -0,0 +1,877 @@ +#ifdef FPU_8087 +static int opFI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxc &= ~0x80; + if (rmdat == 0xe1) + cpu_state.npxc |= 0x80; + wait(3, 0); + return 0; +} +#else +static int opFSTSW_AX(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + AX = cpu_state.npxs; + CLOCK_CYCLES(3); + return 0; +} +#endif + + +static int opFNOP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + CLOCK_CYCLES(4); + return 0; +} + +static int opFCLEX(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= 0xff00; + CLOCK_CYCLES(4); + return 0; +} + +static int opFINIT(uint32_t fetchdat) +{ + uint64_t *p; + FP_ENTER(); + cpu_state.pc++; +#ifdef FPU_8087 + cpu_state.npxc = 0x3FF; +#else + cpu_state.npxc = 0x37F; +#endif + FP_RNPXC(); + cpu_state.npxs = 0; + p = (uint64_t *)cpu_state.tag; + *p = FP_DTAG; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES(17); + CPU_BLOCK_END(); + return 0; +} + + +static int opFFREE(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; + CLOCK_CYCLES(3); + return 0; +} + +static int opFFREEP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; if (cpu_state.abrt) return 1; + x87_pop(); + CLOCK_CYCLES(3); + return 0; +} + +static int opFST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + CLOCK_CYCLES(3); + return 0; +} + +static int opFSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + x87_pop(); + CLOCK_CYCLES(3); + return 0; +} + + + + +static int FSTOR() +{ + uint64_t *p; + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); + x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 14; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); + x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 28; + break; + } + x87_ld_frstor(0); cpu_state.eaaddr += 10; + x87_ld_frstor(1); cpu_state.eaaddr += 10; + x87_ld_frstor(2); cpu_state.eaaddr += 10; + x87_ld_frstor(3); cpu_state.eaaddr += 10; + x87_ld_frstor(4); cpu_state.eaaddr += 10; + x87_ld_frstor(5); cpu_state.eaaddr += 10; + x87_ld_frstor(6); cpu_state.eaaddr += 10; + x87_ld_frstor(7); + + cpu_state.ismmx = 0; + /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *)cpu_state.tag; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && + cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && + !cpu_state.TOP && (*p == FP_CTAG)) + cpu_state.ismmx = 1; + + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + return cpu_state.abrt; +} +static int opFSTOR_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTOR_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; +} +#endif + +static int FSAVE() +{ + uint64_t *p; + + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (FP_TOP(cpu_state.TOP) << 11); + + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + cpu_state.eaaddr+=14; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); + cpu_state.eaaddr+=14; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); + cpu_state.eaaddr+=28; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); + writememl(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); + cpu_state.eaaddr+=28; + if (cpu_state.ismmx) + { + x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; + x87_stmmx(cpu_state.MM[7]); + } + else + { + x87_st_fsave(0); cpu_state.eaaddr+=10; + x87_st_fsave(1); cpu_state.eaaddr+=10; + x87_st_fsave(2); cpu_state.eaaddr+=10; + x87_st_fsave(3); cpu_state.eaaddr+=10; + x87_st_fsave(4); cpu_state.eaaddr+=10; + x87_st_fsave(5); cpu_state.eaaddr+=10; + x87_st_fsave(6); cpu_state.eaaddr+=10; + x87_st_fsave(7); + } + break; + } + + cpu_state.npxc = 0x37F; + FP_RNPXC(); + cpu_state.npxs = 0; + p = (uint64_t *)cpu_state.tag; + *p = FP_DTAG; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + return cpu_state.abrt; +} +static int opFSAVE_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSAVE_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#endif + +static int opFSTSW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTSW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#endif + + +static int opFLD(uint32_t fetchdat) +{ + int old_tag; + uint64_t old_i64; + + FP_ENTER(); + cpu_state.pc++; + old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + x87_push(ST(fetchdat&7)); + cpu_state.tag[FP_TOP(cpu_state.TOP)] = old_tag; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = old_i64; + CLOCK_CYCLES(4); + return 0; +} + +static int opFXCH(uint32_t fetchdat) +{ + double td; + uint8_t old_tag; + uint64_t old_i64; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = ST(fetchdat&7); + ST(fetchdat&7) = td; + old_tag = cpu_state.tag[FP_TOP(cpu_state.TOP)]; + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; + old_i64 = cpu_state.MM[FP_TOP(cpu_state.TOP)].q; + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; + + CLOCK_CYCLES(4); + return 0; +} + +static int opFCHS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = -ST(0); + FP_TAG(); + CLOCK_CYCLES(6); + return 0; +} + +static int opFABS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = fabs(ST(0)); + FP_TAG(); + CLOCK_CYCLES(3); + return 0; +} + +static int opFTST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C2|C3); + if (ST(0) == 0.0) cpu_state.npxs |= C3; + else if (ST(0) < 0.0) cpu_state.npxs |= C0; + CLOCK_CYCLES(4); + return 0; +} + +static int opFXAM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0|C1|C2|C3); + if (cpu_state.tag[cpu_state.TOP&7] == FP_EMPTY) cpu_state.npxs |= (C0|C3); + else if (ST(0) == 0.0) cpu_state.npxs |= C3; + else cpu_state.npxs |= C2; + if (ST(0) < 0.0) cpu_state.npxs |= C1; + CLOCK_CYCLES(8); + return 0; +} + +static int opFLD1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.0); + CLOCK_CYCLES(4); + return 0; +} + +static int opFLDL2T(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.3219280948873623); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDL2E(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.4426950408889634); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDPI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.141592653589793); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDEG2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.3010299956639812); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDLN2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push_u64(0x3fe62e42fefa39f0ull); + CLOCK_CYCLES(8); + return 0; +} + +static int opFLDZ(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.0); + FP_ZTAG(); + CLOCK_CYCLES(4); + return 0; +} + +static int opF2XM1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = pow(2.0, ST(0)) - 1.0; + FP_TAG(); + CLOCK_CYCLES(200); + return 0; +} + +static int opFYL2X(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)) / log(2.0)); + FP_NTAG(); + x87_pop(); + CLOCK_CYCLES(250); + return 0; +} + +static int opFYL2XP1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); + FP_NTAG(); + x87_pop(); + CLOCK_CYCLES(250); + return 0; +} + +static int opFPTAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = tan(ST(0)); + FP_TAG(); + x87_push(1.0); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(235); + return 0; +} + +static int opFPATAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = atan2(ST(1), ST(0)); + FP_NTAG(); + x87_pop(); + CLOCK_CYCLES(250); + return 0; +} + +static int opFDECSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + FP_DECTOP(); + CLOCK_CYCLES(4); + return 0; +} + +static int opFINCSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + FP_INCTOP(); + CLOCK_CYCLES(4); + return 0; +} + +static int opFPREM(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t)(ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double)temp64); + FP_TAG(); + cpu_state.npxs &= ~(C0|C1|C2|C3); + if (temp64 & 4) cpu_state.npxs|=C0; + if (temp64 & 2) cpu_state.npxs|=C3; + if (temp64 & 1) cpu_state.npxs|=C1; + CLOCK_CYCLES(100); + return 0; +} +#ifndef FPU_8087 +static int opFPREM1(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t)(ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double)temp64); + FP_TAG(); + cpu_state.npxs &= ~(C0|C1|C2|C3); + if (temp64 & 4) cpu_state.npxs|=C0; + if (temp64 & 2) cpu_state.npxs|=C3; + if (temp64 & 1) cpu_state.npxs|=C1; + CLOCK_CYCLES(100); + return 0; +} +#endif + +static int opFSQRT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sqrt(ST(0)); + FP_TAG(); + CLOCK_CYCLES(83); + return 0; +} + +#ifndef FPU_8087 +static int opFSINCOS(uint32_t fetchdat) +{ + double td; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = sin(td); + FP_TAG(); + x87_push(cos(td)); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(330); + return 0; +} +#endif + +static int opFRNDINT(uint32_t fetchdat) +{ + double rounded; + FP_ENTER(); + cpu_state.pc++; + rounded = (double) x87_fround(ST(0)); +#ifndef PCEM_CODE + if (rounded > ST(0)) + cpu_state.npxs |= C1; + else + cpu_state.npxs &= ~C1; +#endif + ST(0) = rounded; + FP_TAG(); + CLOCK_CYCLES(21); + return 0; +} + +static int opFSCALE(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t)ST(1); + ST(0) = ST(0) * pow(2.0, (double)temp64); + FP_TAG(); + CLOCK_CYCLES(30); + return 0; +} + +#ifndef FPU_8087 +static int opFSIN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sin(ST(0)); + FP_TAG(); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(300); + return 0; +} + +static int opFCOS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = cos(ST(0)); + FP_TAG(); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(300); + return 0; +} +#endif + + +static int FLDENV() +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); + x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + FP_NNPXC(); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); + x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + } + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + return cpu_state.abrt; +} + +static int opFLDENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFLDENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#endif + +static int opFLDCW_a16(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) return 1; + cpu_state.npxc = tempw; + FP_NNPXC(); + CLOCK_CYCLES(4); + return 0; +} +#ifndef FPU_8087 +static int opFLDCW_a32(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) return 1; + cpu_state.npxc = tempw; + FP_NNPXC(); + CLOCK_CYCLES(4); + return 0; +} +#endif + +static int FSTENV() +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) + { + case 0x000: /*16-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); + writememw(easeg,cpu_state.eaaddr+10,x87_op_off); + writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememw(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); + writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); + writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); + writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); + writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); + writememl(easeg,cpu_state.eaaddr+20,x87_op_off); + writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); + break; + } + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + return cpu_state.abrt; +} + +static int opFSTENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#endif + +static int opFSTCW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int opFSTCW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES(3); + return cpu_state.abrt; +} +#endif + +#ifndef FPU_8087 +#ifdef FP_686 +#define opFCMOV(condition) \ + static int opFCMOV ## condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_ ## condition) \ + { \ + cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES(4); \ + return 0; \ + } + +#define cond_U ( PF_SET()) +#define cond_NU (!PF_SET()) + +opFCMOV(B) +opFCMOV(E) +opFCMOV(BE) +opFCMOV(U) +opFCMOV(NB) +opFCMOV(NE) +opFCMOV(NBE) +opFCMOV(NU) +#endif +#endif diff --git a/src/x87_ops.txt b/src/x87_ops.txt new file mode 100644 index 000000000..28a50cda5 --- /dev/null +++ b/src/x87_ops.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x87_ops.h and CPU_NEW\X87_OPS.H +FC: no differences encountered + diff --git a/src/x87_ops_arith.txt b/src/x87_ops_arith.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/x87_ops_loadstore.txt b/src/x87_ops_loadstore.txt new file mode 100644 index 000000000..ce4583037 --- /dev/null +++ b/src/x87_ops_loadstore.txt @@ -0,0 +1,241 @@ +Comparing files CPU\x87_ops_loadstore.h and CPU_NEW\X87_OPS_LOADSTORE.H +***** CPU\x87_ops_loadstore.h +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ + +static int opFILDiw_a16(uint32_t fetchdat) +{ +***** CPU_NEW\X87_OPS_LOADSTORE.H +static int opFILDiw_a16(uint32_t fetchdat) +{ +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 32767 || temp64 < -32768) + fatal("FISTw overflow %i\n", temp64);*/ + seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP].q = temp64; + FP_LSTAG(); +***** CPU_NEW\X87_OPS_LOADSTORE.H + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP&7].q = temp64; + FP_LSTAG(); +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP].q = temp64; + FP_LSTAG(); +***** CPU_NEW\X87_OPS_LOADSTORE.H + x87_push((double)temp64); + cpu_state.MM[cpu_state.TOP&7].q = temp64; + FP_LSTAG(); +***** + +***** CPU\x87_ops_loadstore.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP].q; + else +***** CPU_NEW\X87_OPS_LOADSTORE.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; + else +***** + +***** CPU\x87_ops_loadstore.h + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP].q; + else +***** CPU_NEW\X87_OPS_LOADSTORE.H + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; + else +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + temp64 = x87_fround(ST(0)); + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + temp64 = x87_fround(ST(0)); +/* if (temp64 > 2147483647 || temp64 < -2147483647) + fatal("FISTl out of range! %i\n", temp64);*/ + seteal((int32_t)temp64); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t=x87_ld80(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); if (cpu_state.abrt) return 1; +***** + +***** CPU\x87_ops_loadstore.h + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; +***** CPU_NEW\X87_OPS_LOADSTORE.H + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); if (cpu_state.abrt) return 1; +***** + diff --git a/src/x87_ops_misc.txt b/src/x87_ops_misc.txt new file mode 100644 index 000000000..985e71950 --- /dev/null +++ b/src/x87_ops_misc.txt @@ -0,0 +1,3 @@ +Comparing files CPU\x87_ops_misc.h and CPU_NEW\X87_OPS_MISC.H +FC: no differences encountered + diff --git a/src/zip.d b/src/zip.d new file mode 100644 index 000000000..0aa1818a4 --- /dev/null +++ b/src/zip.d @@ -0,0 +1,3 @@ +zip.o: disk/zip.c 86box.h timer.h cpu_common/cpu.h config.h device.h \ + piix.h scsi/scsi_device.h nvr.h plat.h lang/language.h ui.h disk/hdc.h \ + disk/hdc_ide.h disk/zip.h