From 490c04fcae2214b4360821725140214a46ba9497 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 29 Feb 2020 19:12:23 +0100 Subject: [PATCH 01/63] Current WIP code. --- src/386.d | 4 + src/386.txt | 3 + src/386_common.d | 4 + src/386_common.txt | 3 + src/386_dynarec.d | 25 + src/386_dynarec.txt | 3 + src/386_dynarec_ops.d | 24 + src/386_dynarec_ops.txt | 3 + src/386_ops.txt | 3 + src/808x.d | 5 + src/808x.txt | 205 + src/{io.h => 86box_io.h} | 0 src/Analog.d | 3 + src/BReverbModel.d | 3 + src/File.d | 3 + src/FileStream.d | 3 + src/LA32FloatWaveGenerator.d | 5 + src/LA32Ramp.d | 3 + src/LA32WaveGenerator.d | 3 + src/MidiStreamParser.d | 4 + src/Part.d | 6 + src/Partial.d | 7 + src/PartialManager.d | 6 + src/Poly.d | 6 + src/ROMInfo.d | 3 + src/SampleRateConverter_dummy.d | 5 + src/Synth.d | 8 + src/TVA.d | 6 + src/TVF.d | 6 + src/TVP.d | 6 + src/Tables.d | 3 + src/acc2168.d | 3 + src/acer_m3a.d | 2 + src/ali1429.d | 3 + src/apm.c | 4 +- src/apm_new.c | 4 +- src/apm_new.d | 1 + src/bootp.d | 9 + src/bugger.c | 2 +- src/bugger.d | 2 + src/c_interface.d | 12 + src/cassette/cassette.c | 203 - src/cassette/cassette.h | 30 - src/cassette/pzx.c | 414 -- src/cassette/pzx.h | 71 - src/cdrom.d | 2 + src/cdrom/cdrom.c | 8 +- src/cdrom/cdrom_image.c | 8 +- src/cdrom/cdrom_image_backend.c | 13 +- src/cdrom_image.d | 3 + src/cdrom_image_backend.d | 2 + src/chipset/acc2168.c | 25 +- src/chipset/acer_m3a.c | 14 +- src/chipset/ali1429.c | 26 +- src/chipset/chipset.h | 5 +- src/chipset/headland.c | 24 +- src/chipset/intel_4x0.c | 1304 ++++- src/chipset/intel_4x0.c.old | 529 ++ src/chipset/neat.c | 18 +- src/chipset/opti495.c | 18 +- src/chipset/scamp.c | 63 +- src/chipset/scat.c | 31 +- src/chipset/sis_85c471.c | 28 +- src/chipset/sis_85c496.c | 39 +- src/chipset/sis_85c50x.c | 16 +- src/chipset/via_mvp3.c | 16 +- src/chipset/wd76c10.c | 22 +- src/cksum.d | 9 + src/codegen.d | 3 + src/codegen_ops.d | 8 + src/codegen_timing_486.d | 4 + src/codegen_timing_686.d | 4 + src/codegen_timing_common.d | 3 + src/codegen_timing_pentium.d | 4 + src/codegen_timing_winchip.d | 4 + src/codegen_x86.d | 4 + src/config.c | 39 +- src/config.d | 6 + src/convolve-sse.d | 4 + src/convolve.d | 1 + src/cpu.d | 4 + src/cpu.txt | 3 + src/cpu/386.c | 256 - src/cpu/codegen.c | 5 +- src/cpu/codegen.h | 5 +- src/cpu/codegen_ops.c | 5 +- src/cpu/codegen_ops_x86-64.h | 5 - src/cpu/codegen_ops_x86.h | 4 - src/cpu/codegen_timing_486.c | 4 +- src/cpu/codegen_timing_686.c | 4 +- src/cpu/codegen_timing_common.c | 2 +- src/cpu/codegen_timing_pentium.c | 4 +- src/cpu/codegen_timing_winchip.c | 2 +- src/cpu/codegen_x86-64.c | 4 +- src/cpu/codegen_x86.c | 6 +- src/cpu/x86_ops_arith_ex.h | 752 --- src/cpu/x86seg.c | 16 +- src/cpu/x87.h | 26 - src/cpu_common.bak/386.c | 335 ++ src/{cpu_new => cpu_common.bak}/386_common.c | 33 +- src/{cpu_new => cpu_common.bak}/386_common.h | 0 .../386_dynarec - Cópia (2).c} | 274 +- src/cpu_common.bak/386_dynarec - Cópia.c | 1008 ++++ src/{cpu_new => cpu_common.bak}/386_dynarec.c | 21 +- src/cpu_common.bak/386_dynarec.c.temp | 900 +++ .../386_dynarec_ops.c | 9 +- src/{cpu => cpu_common.bak}/386_ops.h | 293 +- src/{cpu_new => cpu_common.bak}/808x.c | 63 +- src/cpu_common.bak/codegen_public.h | 62 + src/{cpu_new => cpu_common.bak}/cpu.c | 117 +- src/{cpu => cpu_common.bak}/cpu.h | 173 +- src/{cpu_new => cpu_common.bak}/cpu_table.c | 39 +- src/{cpu_new => cpu_common.bak}/x86.h | 0 src/{cpu_new => cpu_common.bak}/x86_ops.h | 23 +- .../x86_ops_3dnow.h | 0 src/{cpu_new => cpu_common.bak}/x86_ops_amd.h | 0 .../x86_ops_arith.h | 0 .../x86_ops_atomic.h | 0 src/{cpu => cpu_common.bak}/x86_ops_bcd.h | 0 src/{cpu_new => cpu_common.bak}/x86_ops_bit.h | 0 src/{cpu => cpu_common.bak}/x86_ops_bitscan.h | 0 .../x86_ops_flag.h | 0 src/{cpu => cpu_common.bak}/x86_ops_fpu.h | 0 .../x86_ops_i686.h | 16 +- src/{cpu => cpu_common.bak}/x86_ops_inc_dec.h | 0 src/{cpu => cpu_common.bak}/x86_ops_int.h | 0 src/{cpu => cpu_common.bak}/x86_ops_io.h | 0 .../x86_ops_jump.h | 0 src/{cpu => cpu_common.bak}/x86_ops_misc.h | 0 src/{cpu_new => cpu_common.bak}/x86_ops_mmx.h | 0 .../x86_ops_mmx_arith.h | 0 src/{cpu => cpu_common.bak}/x86_ops_mmx_cmp.h | 0 .../x86_ops_mmx_logic.h | 0 .../x86_ops_mmx_mov.h | 0 .../x86_ops_mmx_pack.h | 0 .../x86_ops_mmx_shift.h | 0 src/{cpu_new => cpu_common.bak}/x86_ops_mov.h | 0 .../x86_ops_mov_ctrl.h | 0 src/{cpu => cpu_common.bak}/x86_ops_mov_seg.h | 0 src/{cpu => cpu_common.bak}/x86_ops_movx.h | 0 src/{cpu => cpu_common.bak}/x86_ops_msr.h | 0 src/{cpu => cpu_common.bak}/x86_ops_mul.h | 0 .../x86_ops_pmode.h | 0 src/{cpu => cpu_common.bak}/x86_ops_prefix.h | 0 src/{cpu => cpu_common.bak}/x86_ops_rep.h | 0 src/{cpu => cpu_common.bak}/x86_ops_ret.h | 22 +- src/{cpu => cpu_common.bak}/x86_ops_set.h | 0 .../x86_ops_stack.h | 0 .../x86_ops_string.h | 0 .../x86_ops_xchg.h | 0 src/{cpu => cpu_common.bak}/x86seg.h | 0 src/{cpu_new => cpu_common.bak}/x87.c | 4 +- src/{cpu_new => cpu_common.bak}/x87.h | 0 src/{cpu_new => cpu_common.bak}/x87_ops.h | 0 .../x87_ops_arith.h | 0 .../x87_ops_loadstore.h | 0 .../x87_ops_misc.h | 0 src/cpu_common/386.c | 335 ++ src/cpu_common/386_common.c | 309 ++ src/{cpu => cpu_common}/386_common.h | 53 +- src/cpu_common/386_dynarec - Cópia (2).c | 910 +++ src/cpu_common/386_dynarec - Cópia.c | 1008 ++++ src/cpu_common/386_dynarec.c | 1007 ++++ src/cpu_common/386_dynarec.c.temp | 900 +++ src/{cpu => cpu_common}/386_dynarec_ops.c | 19 +- src/{cpu_new => cpu_common}/386_ops.h | 20 +- src/{cpu => cpu_common}/808x.c | 46 +- src/cpu_common/codegen_public.h | 64 + src/{cpu => cpu_common}/cpu.c | 1033 +++- src/{cpu_new => cpu_common}/cpu.h | 209 +- .../cpu_table - Cópia.c} | 208 +- src/cpu_common/cpu_table.c | 719 +++ src/{cpu => cpu_common}/x86.h | 5 - src/{cpu => cpu_common}/x86_ops.h | 40 +- src/cpu_common/x86_ops_3dnow.h | 346 ++ src/cpu_common/x86_ops_amd.h | 192 + src/{cpu => cpu_common}/x86_ops_arith.h | 2 + src/{cpu => cpu_common}/x86_ops_atomic.h | 32 +- src/{cpu_new => cpu_common}/x86_ops_bcd.h | 0 src/{cpu => cpu_common}/x86_ops_bit.h | 28 +- src/{cpu_new => cpu_common}/x86_ops_bitscan.h | 2 +- src/{cpu => cpu_common}/x86_ops_flag.h | 8 +- src/{cpu_new => cpu_common}/x86_ops_fpu.h | 19 + src/{cpu => cpu_common}/x86_ops_i686.h | 26 +- src/{cpu_new => cpu_common}/x86_ops_inc_dec.h | 4 +- src/{cpu_new => cpu_common}/x86_ops_int.h | 0 src/{cpu_new => cpu_common}/x86_ops_io.h | 0 src/{cpu => cpu_common}/x86_ops_jump.h | 23 + src/{cpu_new => cpu_common}/x86_ops_misc.h | 3 +- src/{cpu => cpu_common}/x86_ops_mmx.h | 4 +- src/{cpu => cpu_common}/x86_ops_mmx_arith.h | 10 +- src/{cpu_new => cpu_common}/x86_ops_mmx_cmp.h | 0 .../x86_ops_mmx_logic.h | 0 src/{cpu => cpu_common}/x86_ops_mmx_mov.h | 20 +- src/{cpu => cpu_common}/x86_ops_mmx_pack.h | 6 +- src/{cpu => cpu_common}/x86_ops_mmx_shift.h | 5 +- src/{cpu => cpu_common}/x86_ops_mov.h | 2 +- src/{cpu => cpu_common}/x86_ops_mov_ctrl.h | 24 +- src/{cpu_new => cpu_common}/x86_ops_mov_seg.h | 0 src/{cpu_new => cpu_common}/x86_ops_movx.h | 0 src/{cpu_new => cpu_common}/x86_ops_msr.h | 0 src/{cpu_new => cpu_common}/x86_ops_mul.h | 32 +- src/{cpu => cpu_common}/x86_ops_pmode.h | 32 +- src/{cpu_new => cpu_common}/x86_ops_prefix.h | 0 src/{cpu_new => cpu_common}/x86_ops_rep.h | 0 src/{cpu_new => cpu_common}/x86_ops_ret.h | 17 +- src/{cpu_new => cpu_common}/x86_ops_set.h | 0 src/{cpu => cpu_common}/x86_ops_stack.h | 28 +- src/{cpu => cpu_common}/x86_ops_string.h | 120 +- src/{cpu => cpu_common}/x86_ops_xchg.h | 6 + src/{cpu_new => cpu_common}/x86seg.h | 0 src/{cpu => cpu_common}/x87.c | 50 +- src/cpu_common/x87.h | 58 + src/{cpu => cpu_common}/x87_ops.h | 146 +- src/cpu_common/x87_ops_arith.h | 435 ++ src/{cpu => cpu_common}/x87_ops_loadstore.h | 12 +- src/{cpu => cpu_common}/x87_ops_misc.h | 113 +- src/cpu_new/386.c | 303 - src/cpu_new/codegen.c | 4 +- src/cpu_new/codegen.h | 2 +- src/cpu_new/codegen_accumulate.c | 4 +- src/cpu_new/codegen_allocator.c | 4 +- src/cpu_new/codegen_backend_arm.c | 4 +- src/cpu_new/codegen_backend_arm64.c | 4 +- src/cpu_new/codegen_backend_arm64_ops.c | 4 +- src/cpu_new/codegen_backend_arm64_uops.c | 4 +- src/cpu_new/codegen_backend_arm_ops.c | 4 +- src/cpu_new/codegen_backend_arm_uops.c | 4 +- src/cpu_new/codegen_backend_x86-64.c | 4 +- src/cpu_new/codegen_backend_x86-64_ops.c | 4 +- src/cpu_new/codegen_backend_x86-64_ops_sse.c | 4 +- src/cpu_new/codegen_backend_x86-64_uops.c | 4 +- src/cpu_new/codegen_backend_x86.c | 4 +- src/cpu_new/codegen_backend_x86_ops.c | 4 +- src/cpu_new/codegen_backend_x86_ops_fpu.c | 4 +- src/cpu_new/codegen_backend_x86_ops_sse.c | 4 +- src/cpu_new/codegen_backend_x86_uops.c | 4 +- src/cpu_new/codegen_block.c | 5 +- src/cpu_new/codegen_ir.c | 4 +- src/cpu_new/codegen_ops.c | 4 +- src/cpu_new/codegen_ops_3dnow.c | 4 +- src/cpu_new/codegen_ops_arith.c | 4 +- src/cpu_new/codegen_ops_branch.c | 4 +- src/cpu_new/codegen_ops_fpu_arith.c | 4 +- src/cpu_new/codegen_ops_fpu_constant.c | 4 +- src/cpu_new/codegen_ops_fpu_loadstore.c | 4 +- src/cpu_new/codegen_ops_fpu_misc.c | 4 +- src/cpu_new/codegen_ops_helpers.c | 4 +- src/cpu_new/codegen_ops_jump.c | 4 +- src/cpu_new/codegen_ops_logic.c | 4 +- src/cpu_new/codegen_ops_misc.c | 4 +- src/cpu_new/codegen_ops_mmx_arith.c | 4 +- src/cpu_new/codegen_ops_mmx_cmp.c | 4 +- src/cpu_new/codegen_ops_mmx_loadstore.c | 4 +- src/cpu_new/codegen_ops_mmx_logic.c | 4 +- src/cpu_new/codegen_ops_mmx_pack.c | 4 +- src/cpu_new/codegen_ops_mmx_shift.c | 4 +- src/cpu_new/codegen_ops_mov.c | 4 +- src/cpu_new/codegen_ops_shift.c | 4 +- src/cpu_new/codegen_ops_stack.c | 4 +- src/cpu_new/codegen_reg.c | 4 +- src/cpu_new/codegen_timing_486.c | 4 +- src/cpu_new/codegen_timing_686.c | 4 +- src/cpu_new/codegen_timing_common.c | 4 +- src/cpu_new/codegen_timing_k6.c | 6 +- src/cpu_new/codegen_timing_pentium.c | 4 +- src/cpu_new/codegen_timing_winchip.c | 4 +- src/cpu_new/codegen_timing_winchip2.c | 4 +- src/cpu_new/x86_flags_dynarec.h | 528 -- src/cpu_new/x86seg.c | 12 +- src/cpu_table.d | 2 + src/cpu_table.txt | 3 + src/debug.d | 9 + src/device.c | 15 +- src/device.d | 2 + src/disk/hdc.c | 6 +- src/disk/hdc_esdi_at.c | 22 +- src/disk/hdc_esdi_mca.c | 20 +- src/disk/hdc_ide.c | 28 +- src/disk/hdc_ide_sff8038i.c | 39 +- src/disk/hdc_ide_sff8038i.h | 5 +- src/disk/hdc_st506_at.c | 18 +- src/disk/hdc_st506_xt.c | 20 +- src/disk/hdc_xta.c | 20 +- src/disk/hdc_xtide.c | 10 +- src/disk/hdd.c | 8 +- src/disk/hdd_image.c | 6 +- src/disk/hdd_table.c | 2 +- src/disk/zip.c | 20 +- src/dma.c | 27 +- src/dma.d | 2 + src/dma.h | 3 +- src/envelope.d | 2 + src/extfilt.d | 2 + src/fdc.d | 2 + src/fdd.d | 4 + src/fdd_86f.d | 3 + src/fdd_common.d | 2 + src/fdd_fdi.d | 3 + src/fdd_imd.d | 3 + src/fdd_img.d | 3 + src/fdd_json.d | 3 + src/fdd_mfm.d | 3 + src/fdd_td0.d | 3 + src/fdi2raw.d | 1 + src/filter.d | 4 + src/floppy/fdc.c | 31 +- src/floppy/fdc.h | 9 +- src/floppy/fdd.c | 8 +- src/floppy/fdd_86f.c | 14 +- src/floppy/fdd_common.c | 4 +- src/floppy/fdd_fdi.c | 6 +- src/floppy/fdd_imd.c | 6 +- src/floppy/fdd_img.c | 8 +- src/floppy/fdd_json.c | 6 +- src/floppy/fdd_mfm.c | 6 +- src/floppy/fdd_td0.c | 6 +- src/floppy/fdi2raw.c | 2 +- src/game/gameport.c | 12 +- src/game/joystick_ch_flightstick_pro.c | 6 +- src/game/joystick_standard.c | 6 +- src/game/joystick_sw_pad.c | 6 +- src/game/joystick_tm_fcs.c | 6 +- src/gameport.d | 4 + src/hdc.d | 2 + src/hdc_esdi_at.d | 3 + src/hdc_esdi_mca.d | 3 + src/hdc_ide.d | 4 + src/hdc_ide_sff8038i.d | 4 + src/hdc_st506_at.d | 3 + src/hdc_st506_xt.d | 3 + src/hdc_xta.d | 3 + src/hdc_xtide.d | 2 + src/hdd.d | 2 + src/hdd_image.d | 2 + src/hdd_table.d | 1 + src/headland.d | 3 + src/i82335.c | 2 +- src/ibm_5161.c | 4 +- src/ibm_5161.d | 3 + src/if.d | 8 + src/intel_4x0.d | 2 + src/intel_flash - Cópia.c | 561 ++ src/intel_flash.c | 38 +- src/intel_flash.d | 2 + src/intel_piix - Cópia.c | 1131 ++++ src/intel_piix.c | 1401 +++-- src/intel_piix.d | 5 + src/intel_sio.c | 8 +- src/intel_sio.d | 3 + src/io.c | 27 +- src/io.d | 1 + src/ip_icmp.d | 9 + src/ip_input.d | 9 + src/ip_output.d | 9 + src/isamem.c | 4 +- src/isamem.d | 2 + src/isartc.c | 6 +- src/isartc.d | 2 + src/joystick_ch_flightstick_pro.d | 3 + src/joystick_standard.d | 2 + src/joystick_sw_pad.d | 2 + src/joystick_tm_fcs.d | 2 + src/keyboard.c | 2 +- src/keyboard.d | 1 + src/keyboard_at.c | 23 +- src/keyboard_at.d | 4 + src/keyboard_xt.c | 14 +- src/keyboard_xt.d | 4 + src/lpt.c | 7 +- src/lpt.d | 2 + src/lpt.h | 5 + src/m_amstrad.d | 5 + src/m_at.d | 3 + src/m_at_286_386sx.d | 3 + src/m_at_386dx_486.d | 4 + src/m_at_commodore.d | 3 + src/m_at_compaq.d | 3 + src/m_at_socket4_5.d | 4 + src/m_at_socket7_s7.d | 4 + src/m_at_socket8.d | 4 + src/m_at_t3100e.d | 3 + src/m_at_t3100e_vid.d | 3 + src/m_europc.d | 4 + src/m_olivetti_m24.d | 4 + src/m_pcjr.d | 4 + src/m_ps1.d | 4 + src/m_ps1_hdc.d | 3 + src/m_ps2_isa.d | 4 + src/m_ps2_mca.d | 4 + src/m_tandy.d | 4 + src/m_xt.d | 3 + src/m_xt_compaq.d | 3 + src/m_xt_t1000.d | 4 + src/m_xt_t1000_vid.d | 3 + src/m_xt_xi8088.d | 4 + src/m_xt_zenith.d | 3 + src/machine.d | 3 + src/machine/m_amstrad.c | 49 +- src/machine/m_at.c | 30 +- src/machine/m_at_286_386sx.c | 50 +- src/machine/m_at_386dx_486.c | 118 +- src/machine/m_at_commodore.c | 20 +- src/machine/m_at_compaq.c | 20 +- src/machine/m_at_socket4_5.c | 70 +- src/machine/m_at_socket7_s7.c | 239 +- src/machine/m_at_socket8.c | 75 +- src/machine/m_at_t3100e.c | 22 +- src/machine/m_at_t3100e_vid.c | 16 +- src/machine/m_europc.c | 32 +- src/machine/m_olivetti_m24.c | 38 +- src/machine/m_pcjr.c | 38 +- src/machine/m_ps1.c | 48 +- src/machine/m_ps1_hdc.c | 20 +- src/machine/m_ps2_isa.c | 38 +- src/machine/m_ps2_mca.c | 52 +- src/machine/m_tandy.c | 35 +- src/machine/m_xt.c | 24 +- src/machine/m_xt_compaq.c | 26 +- src/machine/m_xt_laserxt.c | 28 +- src/machine/m_xt_t1000.c | 36 +- src/machine/m_xt_t1000_vid.c | 16 +- src/machine/m_xt_xi8088.c | 36 +- src/machine/m_xt_zenith.c | 32 +- src/machine/machine.c | 34 +- src/machine/machine.h | 13 +- src/machine/machine_table.c | 138 +- src/machine/machine_table_new.c | 284 - src/machine_table.d | 2 + src/machine_table.txt | 3 + src/mbuf.d | 8 + src/mca.c | 2 +- src/mca.d | 1 + src/mcr.d | 1 + src/mem.c | 547 +- src/mem.d | 4 + src/mem.h | 10 +- src/mem.txt | 2466 +++++++++ src/mem_new.c | 1805 ------ src/midi.d | 2 + src/midi_fluidsynth.d | 2 + src/midi_mt32.d | 5 + src/midi_system.d | 2 + src/misc.d | 8 + src/mouse.d | 1 + src/mouse_bus.c | 2 +- src/mouse_bus.d | 2 + src/mouse_ps2.d | 1 + src/mouse_serial.d | 2 + src/neat.d | 3 + src/net_3c503.d | 3 + src/net_dp8390.d | 2 + src/net_ne2000.d | 3 + src/net_pcap.d | 2 + src/net_pcnet.d | 3 + src/net_slirp.d | 10 + src/net_wd8003.d | 3 + src/network.d | 3 + src/network.rar | Bin 0 -> 204438 bytes src/network/net_3c503.c | 16 +- src/network/net_dp8390.c | 4 +- src/network/net_ne2000.c | 20 +- src/network/net_pcap.c | 11 +- src/network/net_pcnet.c | 72 +- src/network/net_slirp.c | 9 +- src/network/net_wd8003.c | 22 +- src/network/network.c | 11 +- src/network/network.h | 4 +- src/network/pcap_if.c | 6 +- src/nmi.c | 2 +- src/nmi.d | 1 + src/nukedopl.d | 1 + src/nvr.c | 2 +- src/nvr.d | 2 + src/nvr.h | 6 +- src/nvr_at.c | 62 +- src/nvr_at.d | 2 + src/nvr_ps2.c | 4 +- src/nvr_ps2.d | 2 + src/openal.d | 1 + src/opti495.d | 2 + src/pc.c | 53 +- src/pc.d | 9 + src/pcap_if.d | 1 + src/pci.c | 37 +- src/pci.d | 2 + src/pci.h | 19 +- src/pci_dummy.c | 2 +- src/pic.c | 6 +- src/pic.d | 2 + src/piix.h | 7 +- src/pit.c | 9 +- src/pit.d | 3 + src/png.d | 4 + src/port_92.c | 8 +- src/port_92.d | 2 + src/pot.d | 2 + src/ppi.d | 1 + src/printer/png.c | 10 +- src/printer/prt_cpmap.c | 4 +- src/printer/prt_escp.c | 24 +- src/printer/prt_ps.c | 16 +- src/printer/prt_text.c | 12 +- src/prt_cpmap.d | 2 + src/prt_escp.d | 16 + src/prt_ps.d | 3 + src/prt_text.d | 2 + src/queue.d | 1 + src/random.d | 1 + src/rom.c | 4 +- src/rom.d | 2 + src/sbuf.d | 8 + src/scamp.d | 2 + src/scat.d | 3 + src/scsi.d | 4 + src/scsi/scsi.c | 14 +- src/scsi/scsi_aha154x.c | 25 +- src/scsi/scsi_buslogic.c | 26 +- src/scsi/scsi_cdrom.c | 26 +- src/scsi/scsi_device.c | 6 +- src/scsi/scsi_disk.c | 20 +- src/scsi/scsi_ncr5380.c | 22 +- src/scsi/scsi_ncr53c8xx.c | 22 +- src/scsi/scsi_x54x.c | 24 +- src/scsi_aha154x.d | 3 + src/scsi_buslogic.d | 4 + src/scsi_cdrom.d | 4 + src/scsi_device.d | 2 + src/scsi_disk.d | 3 + src/scsi_ncr5380.d | 3 + src/scsi_ncr53c8xx.d | 3 + src/scsi_x54x.d | 4 + src/serial.c | 25 +- src/serial.d | 2 + src/serial.h | 11 +- src/sha1.d | 1 + src/sid.d | 4 + src/sio.h | 8 +- src/sio_acc3221.c | 10 +- src/sio_acc3221.d | 3 + src/sio_detect.c | 6 +- src/sio_fdc37c669.c | 10 +- src/sio_fdc37c669.d | 3 + src/sio_fdc37c66x.c | 10 +- src/sio_fdc37c66x.d | 3 + src/sio_fdc37c67x.c | 519 ++ src/sio_fdc37c93x.c | 10 +- src/sio_fdc37c93x.d | 3 + src/sio_pc87306.c | 23 +- src/sio_pc87306.d | 3 + src/sio_um8669f - Cópia.c | 321 ++ src/sio_um8669f.c | 41 +- src/sio_um8669f.d | 2 + src/sio_w83787f.c | 387 ++ src/sio_w83787f.d | 3 + src/sio_w83877f.c | 162 +- src/sio_w83877f.d | 3 + src/sio_w83977f.c | 519 ++ src/sio_w83977f.d | 3 + src/sis_85c471.d | 3 + src/sis_85c496.d | 3 + src/slirp.d | 9 + src/snd_ad1848.d | 2 + src/snd_adlib.d | 2 + src/snd_adlibgold.d | 3 + src/snd_audiopci.d | 3 + src/snd_cms.d | 1 + src/snd_emu8k.d | 2 + src/snd_gus.d | 2 + src/snd_lpt_dac.d | 2 + src/snd_lpt_dss.d | 2 + src/snd_mpu401.d | 3 + src/snd_opl.d | 2 + src/snd_opl_backend.d | 2 + src/snd_pssj.d | 2 + src/snd_resid.d | 5 + src/snd_sb.d | 4 + src/snd_sb_dsp.d | 3 + src/snd_sn76489.d | 2 + src/snd_speaker.d | 2 + src/snd_ssi2001.d | 2 + src/snd_wss.d | 3 + src/snd_ym7128.d | 1 + src/socket.d | 9 + src/sound.d | 4 + src/sound/midi.c | 15 +- src/sound/midi.h | 13 +- src/sound/midi_fluidsynth.c | 13 +- src/sound/midi_fluidsynth.h | 1 - src/sound/midi_mt32.c | 11 +- src/sound/midi_mt32.h | 2 - src/sound/midi_system.c | 9 +- src/sound/openal.c | 2 +- src/sound/snd_ad1848.c | 8 +- src/sound/snd_ad1848.h | 2 +- src/sound/snd_adlib.c | 11 +- src/sound/snd_adlib.h | 2 - src/sound/snd_adlibgold.c | 14 +- src/sound/snd_adlibgold.h | 1 - src/sound/snd_audiopci.c | 15 +- src/sound/snd_audiopci.h | 1 - src/sound/snd_cms.c | 7 +- src/sound/snd_cms.h | 1 - src/sound/snd_emu8k.c | 12 +- src/sound/snd_gus.c | 15 +- src/sound/snd_gus.h | 1 - src/sound/snd_lpt_dac.c | 11 +- src/sound/snd_lpt_dac.h | 2 - src/sound/snd_lpt_dss.c | 11 +- src/sound/snd_lpt_dss.h | 1 - src/sound/snd_mpu401.c | 77 +- src/sound/snd_mpu401.h | 8 +- src/sound/snd_opl.c | 8 +- src/sound/snd_opl_backend.c | 21 + src/sound/snd_pas16.c | 18 +- src/sound/snd_pas16.h | 1 - src/sound/snd_pssj.c | 13 +- src/sound/snd_pssj.h | 1 - src/sound/snd_resid.cc | 2 +- src/sound/snd_sb.c | 208 +- src/sound/snd_sb.h | 47 - src/sound/snd_sb_dsp.c | 18 +- src/sound/snd_sb_dsp.h | 14 + src/sound/snd_sn76489.c | 6 +- src/sound/snd_speaker.c | 6 +- src/sound/snd_ssi2001.c | 7 +- src/sound/snd_ssi2001.h | 1 - src/sound/snd_wss.c | 15 +- src/sound/snd_wss.h | 25 - src/sound/snd_ym7128.c | 2 +- src/sound/sound.c | 23 +- src/sound/sound.h | 42 + src/sst_flash.c | 177 +- src/sst_flash.d | 2 + src/sst_flash.h | 5 +- src/tcp_input.d | 9 + src/tcp_output.d | 9 + src/tcp_subr.d | 9 + src/tcp_timer.d | 9 + src/timer.d | 1 + src/timer.h | 2 +- src/udp.d | 9 + src/usb.c | 2 +- src/via_mvp3.d | 2 + src/via_vt82c586b.c | 61 +- src/via_vt82c586b.d | 5 + src/vid_ati18800.d | 3 + src/vid_ati28800.d | 3 + src/vid_ati68860_ramdac.d | 3 + src/vid_ati_eeprom.d | 2 + src/vid_ati_mach64.d | 4 + src/vid_att20c49x_ramdac.d | 2 + src/vid_av9194.d | 2 + src/vid_bt48x_ramdac.d | 2 + src/vid_cga.d | 3 + src/vid_cga_comp.d | 2 + src/vid_cl54xx.d | 3 + src/vid_colorplus.d | 3 + src/vid_compaq_cga.d | 3 + src/vid_ega.d | 3 + src/vid_ega_render.d | 2 + src/vid_et4000.d | 3 + src/vid_et4000w32.d | 3 + src/vid_genius.d | 2 + src/vid_hercules.d | 2 + src/vid_herculesplus.d | 2 + src/vid_ht216.d | 3 + src/vid_icd2061.d | 1 + src/vid_ics2595.d | 1 + src/vid_im1024.d | 3 + src/vid_incolor.d | 2 + src/vid_mda.d | 2 + src/vid_mga.d | 3 + src/vid_oak_oti.d | 2 + src/vid_paradise.d | 3 + src/vid_pgc.d | 3 + src/vid_s3.d | 3 + src/vid_s3_virge.d | 3 + src/vid_sc1502x_ramdac.d | 3 + src/vid_sdac_ramdac.d | 2 + src/vid_sigma.d | 2 + src/vid_stg_ramdac.d | 3 + src/vid_svga.d | 3 + src/vid_svga_render.d | 2 + src/vid_table.d | 4 + src/vid_tgui9440.d | 3 + src/vid_ti_cf62011.d | 2 + src/vid_tkd8001_ramdac.d | 2 + src/vid_tvga.d | 3 + src/vid_vga.d | 2 + src/vid_voodoo.d | 4 + src/vid_wy700.d | 2 + src/video.d | 5 + src/video/86Box.exe | Bin 0 -> 23323138 bytes src/video/vid_ati18800.c | 13 +- src/video/vid_ati18800.h | 6 - src/video/vid_ati28800.c | 14 +- src/video/vid_ati28800.h | 9 - src/video/vid_ati68860_ramdac.c | 84 +- src/video/vid_ati68860_ramdac.h | 36 - src/video/vid_ati_eeprom.c | 10 +- src/video/vid_ati_mach64.c | 87 +- src/video/vid_ati_mach64.h | 22 - src/video/vid_att20c49x_ramdac.c | 29 +- src/video/vid_att20c49x_ramdac.h | 32 - src/video/vid_av9194.c | 9 +- src/video/vid_av9194.h | 21 - src/video/vid_bt48x_ramdac.c | 43 +- src/video/vid_bt48x_ramdac.h | 44 - src/video/vid_cga.c | 16 +- src/video/vid_cga_comp.c | 6 +- src/video/vid_cl54xx.c | 27 +- src/video/vid_cl54xx.h | 26 - src/video/vid_colorplus.c | 16 +- src/video/vid_compaq_cga.c | 16 +- src/video/vid_compaq_cga.h | 11 - src/video/vid_ega.c | 17 +- src/video/vid_ega.h | 28 + src/video/vid_ega_render.c | 11 +- src/video/vid_ega_render.h | 42 - src/video/vid_et4000.c | 18 +- src/video/vid_et4000.h | 27 - src/video/vid_et4000w32.c | 18 +- src/video/vid_et4000w32.h | 5 - src/video/vid_genius.c | 19 +- src/video/vid_genius.h | 1 - src/video/vid_hercules.c | 19 +- src/video/vid_hercules.h | 4 - src/video/vid_herculesplus.c | 17 +- src/video/vid_herculesplus.h | 4 - src/video/vid_ht216.c | 17 +- src/video/vid_ht216.h | 21 - src/video/vid_icd2061.c | 27 +- src/video/vid_icd2061.h | 40 - src/video/vid_ics2595.c | 40 +- src/video/vid_ics2595.h | 31 - src/video/vid_im1024.c | 17 +- src/video/vid_im1024.h | 18 - src/video/vid_incolor.c | 17 +- src/video/vid_incolor.h | 4 - src/video/vid_mda.c | 16 +- src/video/vid_mga - Cópia.c | 4876 +++++++++++++++++ src/video/vid_mga.c | 157 +- src/video/vid_mga.h | 18 - src/video/vid_oak_oti.c | 13 +- src/video/vid_oak_oti.h | 8 - src/video/vid_paradise.c | 13 +- src/video/vid_paradise.h | 9 - src/video/vid_pgc.c | 16 +- src/video/vid_pgc.h | 3 - src/video/vid_s3.c | 38 +- src/video/vid_s3.h | 39 - src/video/vid_s3_virge.c | 17 +- src/video/vid_s3_virge.h | 11 - src/video/vid_sc1502x_ramdac.c | 17 +- src/video/vid_sc1502x_ramdac.h | 30 - src/video/vid_sdac_ramdac.c | 25 +- src/video/vid_sdac_ramdac.h | 33 - src/video/vid_sigma.c | 19 +- src/video/vid_sigma.h | 2 - src/video/vid_stg_ramdac.c | 16 +- src/video/vid_stg_ramdac.h | 30 - src/video/vid_svga.c | 16 +- src/video/vid_svga.h | 75 +- src/video/vid_svga_render.c | 6 +- src/video/vid_table.c | 38 +- src/video/vid_tgui9440.c | 20 +- src/video/vid_tgui9440.h | 6 - src/video/vid_ti_cf62011.c | 18 +- src/video/vid_ti_cf62011.h | 4 - src/video/vid_tkd8001_ramdac.c | 24 +- src/video/vid_tkd8001_ramdac.h | 28 - src/video/vid_tvga.c | 14 +- src/video/vid_tvga.h | 5 - src/video/vid_vga.c | 13 +- src/video/vid_vga.h | 6 - src/video/vid_voodoo.c | 21 +- src/video/vid_voodoo.h | 1 - src/video/vid_wy700.c | 13 +- src/video/vid_wy700.h | 1 - src/video/video.c | 16 +- src/video/video.h | 160 + src/vnc.c | 2 +- src/voice.d | 4 + src/wave.d | 2 + src/wave6581_PST.d | 2 + src/wave6581_PS_.d | 2 + src/wave6581_P_T.d | 2 + src/wave6581__ST.d | 2 + src/wave8580_PST.d | 2 + src/wave8580_PS_.d | 2 + src/wave8580_P_T.d | 2 + src/wave8580__ST.d | 2 + src/wd76c10.d | 3 + src/win.d | 3 + src/win/Makefile.mingw | 29 +- src/win/Makefile_ndr.mingw | 26 +- src/win/win.c | 20 +- src/win/win_about.c | 4 +- src/win/win_cdrom.c | 16 +- src/win/win_crashdump.c | 4 +- src/win/win_d2d.c | 12 +- src/win/win_devconf.c | 12 +- src/win/win_dialog.c | 8 +- src/win/win_discord.c | 14 +- src/win/win_dynld.c | 4 +- src/win/win_joystick.cpp | 8 +- src/win/win_joystick_xinput.cpp | 8 +- src/win/win_jsconf.c | 10 +- src/win/win_keyboard.c | 8 +- src/win/win_midi.c | 10 +- src/win/win_mouse.c | 6 +- src/win/win_new_floppy.c | 12 +- src/win/win_opendir.c | 4 +- src/win/win_sdl.c | 12 +- src/win/win_settings.c | 62 +- src/win/win_snd_gain.c | 8 +- src/win/win_stbar.c | 42 +- src/win/win_thread.c | 4 +- src/win/win_ui.c | 20 +- src/win_about.d | 2 + src/win_cdrom.d | 3 + src/win_devconf.d | 2 + src/win_dialog.d | 2 + src/win_discord.d | 3 + src/win_dynld.d | 1 + src/win_joystick.d | 2 + src/win_jsconf.d | 2 + src/win_keyboard.d | 2 + src/win_midi.d | 2 + src/win_mouse.d | 2 + src/win_new_floppy.d | 2 + src/win_sdl.d | 2 + src/win_settings.d | 7 + src/win_snd_gain.d | 2 + src/win_stbar.d | 5 + src/win_thread.d | 1 + src/win_ui.d | 3 + src/x86.txt | 785 +++ src/x86_flags.txt | 835 +++ src/x86_ops_arith.txt | 11 + src/x86_ops_atomic.txt | 161 + src/x86_ops_bcd.txt | 3 + src/x86_ops_bit.txt | 157 + src/x86_ops_bitscan.txt | 11 + src/x86_ops_call.txt | 173 + src/x86_ops_flag.txt | 78 + src/x86_ops_fpu.txt | 12 + src/x86_ops_jump.txt | 21 + src/x86_ops_misc.txt | 10 + src/x86_ops_mmx.txt | 23 + src/x86_ops_mmx_shift.txt | 38 + src/x86_ops_mov.txt | 15 + src/x86_ops_mov_ctrl.txt | 163 + src/x86_ops_mov_seg.txt | 3 + src/x86_ops_movx.txt | 3 + src/x86_ops_msr.txt | 3 + src/x86_ops_mul.txt | 121 + src/x86_ops_pmode.txt | 206 + src/x86_ops_prefix.txt | 3 + src/x86_ops_rep.txt | 3 + src/x86_ops_ret.txt | 66 + src/x86_ops_set.txt | 3 + src/x86_ops_shift.txt | 126 + src/x86_ops_stack.txt | 65 + src/x86_ops_string.txt | 553 ++ src/x86_ops_xchg.txt | 55 + src/x86_seg.txt | 0 src/x86seg.d | 3 + src/x86seg.txt | 0 src/x87.d | 3 + src/x87.txt | 3 + src/x87_bak/x87.h | 58 + src/x87_bak/x87_ops.h | 2147 ++++++++ src/{cpu => x87_bak}/x87_ops_arith.h | 52 +- src/x87_bak/x87_ops_loadstore.h | 492 ++ src/x87_bak/x87_ops_misc.h | 877 +++ src/x87_ops.txt | 3 + src/x87_ops_arith.txt | 0 src/x87_ops_loadstore.txt | 241 + src/x87_ops_misc.txt | 3 + src/zip.d | 3 + 882 files changed, 37763 insertions(+), 9455 deletions(-) create mode 100644 src/386.d create mode 100644 src/386.txt create mode 100644 src/386_common.d create mode 100644 src/386_common.txt create mode 100644 src/386_dynarec.d create mode 100644 src/386_dynarec.txt create mode 100644 src/386_dynarec_ops.d create mode 100644 src/386_dynarec_ops.txt create mode 100644 src/386_ops.txt create mode 100644 src/808x.d create mode 100644 src/808x.txt rename src/{io.h => 86box_io.h} (100%) create mode 100644 src/Analog.d create mode 100644 src/BReverbModel.d create mode 100644 src/File.d create mode 100644 src/FileStream.d create mode 100644 src/LA32FloatWaveGenerator.d create mode 100644 src/LA32Ramp.d create mode 100644 src/LA32WaveGenerator.d create mode 100644 src/MidiStreamParser.d create mode 100644 src/Part.d create mode 100644 src/Partial.d create mode 100644 src/PartialManager.d create mode 100644 src/Poly.d create mode 100644 src/ROMInfo.d create mode 100644 src/SampleRateConverter_dummy.d create mode 100644 src/Synth.d create mode 100644 src/TVA.d create mode 100644 src/TVF.d create mode 100644 src/TVP.d create mode 100644 src/Tables.d create mode 100644 src/acc2168.d create mode 100644 src/acer_m3a.d create mode 100644 src/ali1429.d create mode 100644 src/apm_new.d create mode 100644 src/bootp.d create mode 100644 src/bugger.d create mode 100644 src/c_interface.d delete mode 100644 src/cassette/cassette.c delete mode 100644 src/cassette/cassette.h delete mode 100644 src/cassette/pzx.c delete mode 100644 src/cassette/pzx.h create mode 100644 src/cdrom.d create mode 100644 src/cdrom_image.d create mode 100644 src/cdrom_image_backend.d create mode 100644 src/chipset/intel_4x0.c.old create mode 100644 src/cksum.d create mode 100644 src/codegen.d create mode 100644 src/codegen_ops.d create mode 100644 src/codegen_timing_486.d create mode 100644 src/codegen_timing_686.d create mode 100644 src/codegen_timing_common.d create mode 100644 src/codegen_timing_pentium.d create mode 100644 src/codegen_timing_winchip.d create mode 100644 src/codegen_x86.d create mode 100644 src/config.d create mode 100644 src/convolve-sse.d create mode 100644 src/convolve.d create mode 100644 src/cpu.d create mode 100644 src/cpu.txt delete mode 100644 src/cpu/386.c delete mode 100644 src/cpu/x86_ops_arith_ex.h delete mode 100644 src/cpu/x87.h create mode 100644 src/cpu_common.bak/386.c rename src/{cpu_new => cpu_common.bak}/386_common.c (93%) rename src/{cpu_new => cpu_common.bak}/386_common.h (100%) rename src/{cpu/386_dynarec.c => cpu_common.bak/386_dynarec - Cópia (2).c} (85%) create mode 100644 src/cpu_common.bak/386_dynarec - Cópia.c rename src/{cpu_new => cpu_common.bak}/386_dynarec.c (99%) create mode 100644 src/cpu_common.bak/386_dynarec.c.temp rename src/{cpu_new => cpu_common.bak}/386_dynarec_ops.c (95%) rename src/{cpu => cpu_common.bak}/386_ops.h (82%) rename src/{cpu_new => cpu_common.bak}/808x.c (98%) create mode 100644 src/cpu_common.bak/codegen_public.h rename src/{cpu_new => cpu_common.bak}/cpu.c (97%) rename src/{cpu => cpu_common.bak}/cpu.h (80%) rename src/{cpu_new => cpu_common.bak}/cpu_table.c (98%) rename src/{cpu_new => cpu_common.bak}/x86.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops.h (95%) rename src/{cpu_new => cpu_common.bak}/x86_ops_3dnow.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_amd.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_arith.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_atomic.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_bcd.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_bit.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_bitscan.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_flag.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_fpu.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_i686.h (98%) rename src/{cpu => cpu_common.bak}/x86_ops_inc_dec.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_int.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_io.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_jump.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_misc.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mmx.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mmx_arith.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_mmx_cmp.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_mmx_logic.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mmx_mov.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mmx_pack.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mmx_shift.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mov.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_mov_ctrl.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_mov_seg.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_movx.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_msr.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_mul.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_pmode.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_prefix.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_rep.h (100%) rename src/{cpu => cpu_common.bak}/x86_ops_ret.h (96%) rename src/{cpu => cpu_common.bak}/x86_ops_set.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_stack.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_string.h (100%) rename src/{cpu_new => cpu_common.bak}/x86_ops_xchg.h (100%) rename src/{cpu => cpu_common.bak}/x86seg.h (100%) rename src/{cpu_new => cpu_common.bak}/x87.c (98%) rename src/{cpu_new => cpu_common.bak}/x87.h (100%) rename src/{cpu_new => cpu_common.bak}/x87_ops.h (100%) rename src/{cpu_new => cpu_common.bak}/x87_ops_arith.h (100%) rename src/{cpu_new => cpu_common.bak}/x87_ops_loadstore.h (100%) rename src/{cpu_new => cpu_common.bak}/x87_ops_misc.h (100%) create mode 100644 src/cpu_common/386.c create mode 100644 src/cpu_common/386_common.c rename src/{cpu => cpu_common}/386_common.h (77%) create mode 100644 src/cpu_common/386_dynarec - Cópia (2).c create mode 100644 src/cpu_common/386_dynarec - Cópia.c create mode 100644 src/cpu_common/386_dynarec.c create mode 100644 src/cpu_common/386_dynarec.c.temp rename src/{cpu => cpu_common}/386_dynarec_ops.c (90%) rename src/{cpu_new => cpu_common}/386_ops.h (99%) rename src/{cpu => cpu_common}/808x.c (98%) create mode 100644 src/cpu_common/codegen_public.h rename src/{cpu => cpu_common}/cpu.c (70%) rename src/{cpu_new => cpu_common}/cpu.h (75%) rename src/{cpu/cpu_table.c => cpu_common/cpu_table - Cópia.c} (75%) create mode 100644 src/cpu_common/cpu_table.c rename src/{cpu => cpu_common}/x86.h (96%) rename src/{cpu => cpu_common}/x86_ops.h (89%) create mode 100644 src/cpu_common/x86_ops_3dnow.h create mode 100644 src/cpu_common/x86_ops_amd.h rename src/{cpu => cpu_common}/x86_ops_arith.h (99%) rename src/{cpu => cpu_common}/x86_ops_atomic.h (92%) rename src/{cpu_new => cpu_common}/x86_ops_bcd.h (100%) rename src/{cpu => cpu_common}/x86_ops_bit.h (94%) rename src/{cpu_new => cpu_common}/x86_ops_bitscan.h (99%) rename src/{cpu => cpu_common}/x86_ops_flag.h (98%) rename src/{cpu_new => cpu_common}/x86_ops_fpu.h (72%) rename src/{cpu => cpu_common}/x86_ops_i686.h (96%) rename src/{cpu_new => cpu_common}/x86_ops_inc_dec.h (97%) rename src/{cpu_new => cpu_common}/x86_ops_int.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_io.h (100%) rename src/{cpu => cpu_common}/x86_ops_jump.h (90%) rename src/{cpu_new => cpu_common}/x86_ops_misc.h (99%) rename src/{cpu => cpu_common}/x86_ops_mmx.h (95%) rename src/{cpu => cpu_common}/x86_ops_mmx_arith.h (99%) rename src/{cpu_new => cpu_common}/x86_ops_mmx_cmp.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_mmx_logic.h (100%) rename src/{cpu => cpu_common}/x86_ops_mmx_mov.h (92%) rename src/{cpu => cpu_common}/x86_ops_mmx_pack.h (98%) rename src/{cpu => cpu_common}/x86_ops_mmx_shift.h (97%) rename src/{cpu => cpu_common}/x86_ops_mov.h (99%) rename src/{cpu => cpu_common}/x86_ops_mov_ctrl.h (88%) rename src/{cpu_new => cpu_common}/x86_ops_mov_seg.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_movx.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_msr.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_mul.h (96%) rename src/{cpu => cpu_common}/x86_ops_pmode.h (94%) rename src/{cpu_new => cpu_common}/x86_ops_prefix.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_rep.h (100%) rename src/{cpu_new => cpu_common}/x86_ops_ret.h (96%) rename src/{cpu_new => cpu_common}/x86_ops_set.h (100%) rename src/{cpu => cpu_common}/x86_ops_stack.h (97%) rename src/{cpu => cpu_common}/x86_ops_string.h (85%) rename src/{cpu => cpu_common}/x86_ops_xchg.h (99%) rename src/{cpu_new => cpu_common}/x86seg.h (100%) rename src/{cpu => cpu_common}/x87.c (64%) create mode 100644 src/cpu_common/x87.h rename src/{cpu => cpu_common}/x87_ops.h (97%) create mode 100644 src/cpu_common/x87_ops_arith.h rename src/{cpu => cpu_common}/x87_ops_loadstore.h (97%) rename src/{cpu => cpu_common}/x87_ops_misc.h (88%) delete mode 100644 src/cpu_new/386.c delete mode 100644 src/cpu_new/x86_flags_dynarec.h create mode 100644 src/cpu_table.d create mode 100644 src/cpu_table.txt create mode 100644 src/debug.d create mode 100644 src/device.d create mode 100644 src/dma.d create mode 100644 src/envelope.d create mode 100644 src/extfilt.d create mode 100644 src/fdc.d create mode 100644 src/fdd.d create mode 100644 src/fdd_86f.d create mode 100644 src/fdd_common.d create mode 100644 src/fdd_fdi.d create mode 100644 src/fdd_imd.d create mode 100644 src/fdd_img.d create mode 100644 src/fdd_json.d create mode 100644 src/fdd_mfm.d create mode 100644 src/fdd_td0.d create mode 100644 src/fdi2raw.d create mode 100644 src/filter.d create mode 100644 src/gameport.d create mode 100644 src/hdc.d create mode 100644 src/hdc_esdi_at.d create mode 100644 src/hdc_esdi_mca.d create mode 100644 src/hdc_ide.d create mode 100644 src/hdc_ide_sff8038i.d create mode 100644 src/hdc_st506_at.d create mode 100644 src/hdc_st506_xt.d create mode 100644 src/hdc_xta.d create mode 100644 src/hdc_xtide.d create mode 100644 src/hdd.d create mode 100644 src/hdd_image.d create mode 100644 src/hdd_table.d create mode 100644 src/headland.d create mode 100644 src/ibm_5161.d create mode 100644 src/if.d create mode 100644 src/intel_4x0.d create mode 100644 src/intel_flash - Cópia.c create mode 100644 src/intel_flash.d create mode 100644 src/intel_piix - Cópia.c create mode 100644 src/intel_piix.d create mode 100644 src/intel_sio.d create mode 100644 src/io.d create mode 100644 src/ip_icmp.d create mode 100644 src/ip_input.d create mode 100644 src/ip_output.d create mode 100644 src/isamem.d create mode 100644 src/isartc.d create mode 100644 src/joystick_ch_flightstick_pro.d create mode 100644 src/joystick_standard.d create mode 100644 src/joystick_sw_pad.d create mode 100644 src/joystick_tm_fcs.d create mode 100644 src/keyboard.d create mode 100644 src/keyboard_at.d create mode 100644 src/keyboard_xt.d create mode 100644 src/lpt.d create mode 100644 src/m_amstrad.d create mode 100644 src/m_at.d create mode 100644 src/m_at_286_386sx.d create mode 100644 src/m_at_386dx_486.d create mode 100644 src/m_at_commodore.d create mode 100644 src/m_at_compaq.d create mode 100644 src/m_at_socket4_5.d create mode 100644 src/m_at_socket7_s7.d create mode 100644 src/m_at_socket8.d create mode 100644 src/m_at_t3100e.d create mode 100644 src/m_at_t3100e_vid.d create mode 100644 src/m_europc.d create mode 100644 src/m_olivetti_m24.d create mode 100644 src/m_pcjr.d create mode 100644 src/m_ps1.d create mode 100644 src/m_ps1_hdc.d create mode 100644 src/m_ps2_isa.d create mode 100644 src/m_ps2_mca.d create mode 100644 src/m_tandy.d create mode 100644 src/m_xt.d create mode 100644 src/m_xt_compaq.d create mode 100644 src/m_xt_t1000.d create mode 100644 src/m_xt_t1000_vid.d create mode 100644 src/m_xt_xi8088.d create mode 100644 src/m_xt_zenith.d create mode 100644 src/machine.d delete mode 100644 src/machine/machine_table_new.c create mode 100644 src/machine_table.d create mode 100644 src/machine_table.txt create mode 100644 src/mbuf.d create mode 100644 src/mca.d create mode 100644 src/mcr.d create mode 100644 src/mem.d create mode 100644 src/mem.txt delete mode 100644 src/mem_new.c create mode 100644 src/midi.d create mode 100644 src/midi_fluidsynth.d create mode 100644 src/midi_mt32.d create mode 100644 src/midi_system.d create mode 100644 src/misc.d create mode 100644 src/mouse.d create mode 100644 src/mouse_bus.d create mode 100644 src/mouse_ps2.d create mode 100644 src/mouse_serial.d create mode 100644 src/neat.d create mode 100644 src/net_3c503.d create mode 100644 src/net_dp8390.d create mode 100644 src/net_ne2000.d create mode 100644 src/net_pcap.d create mode 100644 src/net_pcnet.d create mode 100644 src/net_slirp.d create mode 100644 src/net_wd8003.d create mode 100644 src/network.d create mode 100644 src/network.rar create mode 100644 src/nmi.d create mode 100644 src/nukedopl.d create mode 100644 src/nvr.d create mode 100644 src/nvr_at.d create mode 100644 src/nvr_ps2.d create mode 100644 src/openal.d create mode 100644 src/opti495.d create mode 100644 src/pc.d create mode 100644 src/pcap_if.d create mode 100644 src/pci.d create mode 100644 src/pic.d create mode 100644 src/pit.d create mode 100644 src/png.d create mode 100644 src/port_92.d create mode 100644 src/pot.d create mode 100644 src/ppi.d create mode 100644 src/prt_cpmap.d create mode 100644 src/prt_escp.d create mode 100644 src/prt_ps.d create mode 100644 src/prt_text.d create mode 100644 src/queue.d create mode 100644 src/random.d create mode 100644 src/rom.d create mode 100644 src/sbuf.d create mode 100644 src/scamp.d create mode 100644 src/scat.d create mode 100644 src/scsi.d create mode 100644 src/scsi_aha154x.d create mode 100644 src/scsi_buslogic.d create mode 100644 src/scsi_cdrom.d create mode 100644 src/scsi_device.d create mode 100644 src/scsi_disk.d create mode 100644 src/scsi_ncr5380.d create mode 100644 src/scsi_ncr53c8xx.d create mode 100644 src/scsi_x54x.d create mode 100644 src/serial.d create mode 100644 src/sha1.d create mode 100644 src/sid.d create mode 100644 src/sio_acc3221.d create mode 100644 src/sio_fdc37c669.d create mode 100644 src/sio_fdc37c66x.d create mode 100644 src/sio_fdc37c67x.c create mode 100644 src/sio_fdc37c93x.d create mode 100644 src/sio_pc87306.d create mode 100644 src/sio_um8669f - Cópia.c create mode 100644 src/sio_um8669f.d create mode 100644 src/sio_w83787f.c create mode 100644 src/sio_w83787f.d create mode 100644 src/sio_w83877f.d create mode 100644 src/sio_w83977f.c create mode 100644 src/sio_w83977f.d create mode 100644 src/sis_85c471.d create mode 100644 src/sis_85c496.d create mode 100644 src/slirp.d create mode 100644 src/snd_ad1848.d create mode 100644 src/snd_adlib.d create mode 100644 src/snd_adlibgold.d create mode 100644 src/snd_audiopci.d create mode 100644 src/snd_cms.d create mode 100644 src/snd_emu8k.d create mode 100644 src/snd_gus.d create mode 100644 src/snd_lpt_dac.d create mode 100644 src/snd_lpt_dss.d create mode 100644 src/snd_mpu401.d create mode 100644 src/snd_opl.d create mode 100644 src/snd_opl_backend.d create mode 100644 src/snd_pssj.d create mode 100644 src/snd_resid.d create mode 100644 src/snd_sb.d create mode 100644 src/snd_sb_dsp.d create mode 100644 src/snd_sn76489.d create mode 100644 src/snd_speaker.d create mode 100644 src/snd_ssi2001.d create mode 100644 src/snd_wss.d create mode 100644 src/snd_ym7128.d create mode 100644 src/socket.d create mode 100644 src/sound.d delete mode 100644 src/sound/midi_fluidsynth.h delete mode 100644 src/sound/midi_mt32.h delete mode 100644 src/sound/snd_adlib.h delete mode 100644 src/sound/snd_adlibgold.h delete mode 100644 src/sound/snd_audiopci.h delete mode 100644 src/sound/snd_cms.h delete mode 100644 src/sound/snd_gus.h delete mode 100644 src/sound/snd_lpt_dac.h delete mode 100644 src/sound/snd_lpt_dss.h delete mode 100644 src/sound/snd_pas16.h delete mode 100644 src/sound/snd_pssj.h delete mode 100644 src/sound/snd_sb.h delete mode 100644 src/sound/snd_ssi2001.h delete mode 100644 src/sound/snd_wss.h create mode 100644 src/sst_flash.d create mode 100644 src/tcp_input.d create mode 100644 src/tcp_output.d create mode 100644 src/tcp_subr.d create mode 100644 src/tcp_timer.d create mode 100644 src/timer.d create mode 100644 src/udp.d create mode 100644 src/via_mvp3.d create mode 100644 src/via_vt82c586b.d create mode 100644 src/vid_ati18800.d create mode 100644 src/vid_ati28800.d create mode 100644 src/vid_ati68860_ramdac.d create mode 100644 src/vid_ati_eeprom.d create mode 100644 src/vid_ati_mach64.d create mode 100644 src/vid_att20c49x_ramdac.d create mode 100644 src/vid_av9194.d create mode 100644 src/vid_bt48x_ramdac.d create mode 100644 src/vid_cga.d create mode 100644 src/vid_cga_comp.d create mode 100644 src/vid_cl54xx.d create mode 100644 src/vid_colorplus.d create mode 100644 src/vid_compaq_cga.d create mode 100644 src/vid_ega.d create mode 100644 src/vid_ega_render.d create mode 100644 src/vid_et4000.d create mode 100644 src/vid_et4000w32.d create mode 100644 src/vid_genius.d create mode 100644 src/vid_hercules.d create mode 100644 src/vid_herculesplus.d create mode 100644 src/vid_ht216.d create mode 100644 src/vid_icd2061.d create mode 100644 src/vid_ics2595.d create mode 100644 src/vid_im1024.d create mode 100644 src/vid_incolor.d create mode 100644 src/vid_mda.d create mode 100644 src/vid_mga.d create mode 100644 src/vid_oak_oti.d create mode 100644 src/vid_paradise.d create mode 100644 src/vid_pgc.d create mode 100644 src/vid_s3.d create mode 100644 src/vid_s3_virge.d create mode 100644 src/vid_sc1502x_ramdac.d create mode 100644 src/vid_sdac_ramdac.d create mode 100644 src/vid_sigma.d create mode 100644 src/vid_stg_ramdac.d create mode 100644 src/vid_svga.d create mode 100644 src/vid_svga_render.d create mode 100644 src/vid_table.d create mode 100644 src/vid_tgui9440.d create mode 100644 src/vid_ti_cf62011.d create mode 100644 src/vid_tkd8001_ramdac.d create mode 100644 src/vid_tvga.d create mode 100644 src/vid_vga.d create mode 100644 src/vid_voodoo.d create mode 100644 src/vid_wy700.d create mode 100644 src/video.d create mode 100644 src/video/86Box.exe delete mode 100644 src/video/vid_ati18800.h delete mode 100644 src/video/vid_ati28800.h delete mode 100644 src/video/vid_ati68860_ramdac.h delete mode 100644 src/video/vid_ati_mach64.h delete mode 100644 src/video/vid_att20c49x_ramdac.h delete mode 100644 src/video/vid_av9194.h delete mode 100644 src/video/vid_bt48x_ramdac.h delete mode 100644 src/video/vid_cl54xx.h delete mode 100644 src/video/vid_compaq_cga.h delete mode 100644 src/video/vid_ega_render.h delete mode 100644 src/video/vid_et4000.h delete mode 100644 src/video/vid_et4000w32.h delete mode 100644 src/video/vid_genius.h delete mode 100644 src/video/vid_hercules.h delete mode 100644 src/video/vid_herculesplus.h delete mode 100644 src/video/vid_ht216.h delete mode 100644 src/video/vid_icd2061.h delete mode 100644 src/video/vid_ics2595.h delete mode 100644 src/video/vid_im1024.h delete mode 100644 src/video/vid_incolor.h create mode 100644 src/video/vid_mga - Cópia.c delete mode 100644 src/video/vid_mga.h delete mode 100644 src/video/vid_oak_oti.h delete mode 100644 src/video/vid_paradise.h delete mode 100644 src/video/vid_s3.h delete mode 100644 src/video/vid_s3_virge.h delete mode 100644 src/video/vid_sc1502x_ramdac.h delete mode 100644 src/video/vid_sdac_ramdac.h delete mode 100644 src/video/vid_sigma.h delete mode 100644 src/video/vid_stg_ramdac.h delete mode 100644 src/video/vid_tgui9440.h delete mode 100644 src/video/vid_ti_cf62011.h delete mode 100644 src/video/vid_tkd8001_ramdac.h delete mode 100644 src/video/vid_tvga.h delete mode 100644 src/video/vid_vga.h delete mode 100644 src/video/vid_voodoo.h delete mode 100644 src/video/vid_wy700.h create mode 100644 src/voice.d create mode 100644 src/wave.d create mode 100644 src/wave6581_PST.d create mode 100644 src/wave6581_PS_.d create mode 100644 src/wave6581_P_T.d create mode 100644 src/wave6581__ST.d create mode 100644 src/wave8580_PST.d create mode 100644 src/wave8580_PS_.d create mode 100644 src/wave8580_P_T.d create mode 100644 src/wave8580__ST.d create mode 100644 src/wd76c10.d create mode 100644 src/win.d create mode 100644 src/win_about.d create mode 100644 src/win_cdrom.d create mode 100644 src/win_devconf.d create mode 100644 src/win_dialog.d create mode 100644 src/win_discord.d create mode 100644 src/win_dynld.d create mode 100644 src/win_joystick.d create mode 100644 src/win_jsconf.d create mode 100644 src/win_keyboard.d create mode 100644 src/win_midi.d create mode 100644 src/win_mouse.d create mode 100644 src/win_new_floppy.d create mode 100644 src/win_sdl.d create mode 100644 src/win_settings.d create mode 100644 src/win_snd_gain.d create mode 100644 src/win_stbar.d create mode 100644 src/win_thread.d create mode 100644 src/win_ui.d create mode 100644 src/x86.txt create mode 100644 src/x86_flags.txt create mode 100644 src/x86_ops_arith.txt create mode 100644 src/x86_ops_atomic.txt create mode 100644 src/x86_ops_bcd.txt create mode 100644 src/x86_ops_bit.txt create mode 100644 src/x86_ops_bitscan.txt create mode 100644 src/x86_ops_call.txt create mode 100644 src/x86_ops_flag.txt create mode 100644 src/x86_ops_fpu.txt create mode 100644 src/x86_ops_jump.txt create mode 100644 src/x86_ops_misc.txt create mode 100644 src/x86_ops_mmx.txt create mode 100644 src/x86_ops_mmx_shift.txt create mode 100644 src/x86_ops_mov.txt create mode 100644 src/x86_ops_mov_ctrl.txt create mode 100644 src/x86_ops_mov_seg.txt create mode 100644 src/x86_ops_movx.txt create mode 100644 src/x86_ops_msr.txt create mode 100644 src/x86_ops_mul.txt create mode 100644 src/x86_ops_pmode.txt create mode 100644 src/x86_ops_prefix.txt create mode 100644 src/x86_ops_rep.txt create mode 100644 src/x86_ops_ret.txt create mode 100644 src/x86_ops_set.txt create mode 100644 src/x86_ops_shift.txt create mode 100644 src/x86_ops_stack.txt create mode 100644 src/x86_ops_string.txt create mode 100644 src/x86_ops_xchg.txt create mode 100644 src/x86_seg.txt create mode 100644 src/x86seg.d create mode 100644 src/x86seg.txt create mode 100644 src/x87.d create mode 100644 src/x87.txt create mode 100644 src/x87_bak/x87.h create mode 100644 src/x87_bak/x87_ops.h rename src/{cpu => x87_bak}/x87_ops_arith.h (88%) create mode 100644 src/x87_bak/x87_ops_loadstore.h create mode 100644 src/x87_bak/x87_ops_misc.h create mode 100644 src/x87_ops.txt create mode 100644 src/x87_ops_arith.txt create mode 100644 src/x87_ops_loadstore.txt create mode 100644 src/x87_ops_misc.txt create mode 100644 src/zip.d 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 0000000000000000000000000000000000000000..363c66769d7f4811f61e70b7541bb22fe308816f GIT binary patch literal 204438 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%0Aua)vJz@N@2l=)_ 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 O?LzORr-^d|2>2hUPd!fn literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..56b0faadcbce8fe6dee35e7a4d0938a8145b33d6 GIT binary patch literal 23323138 zcmeFadw3K@)(6}(nSlX<9VF4H0R|itc3BA;+@OgD5?EB!C@i9&;;Jn8B3_t5RD=mL z1Je!z(S`Ny8sjSNx-RP_1W?HZGF-d_a1}x2=B0;0ji?aNCExE?)jiW0g73c1?jPUx zJRd%$tE*0(Tb(*pb^3JA<=0gz8H%Df@PAvIqSWHbeE6Ao z$3R^^Qc=d(PFCLj+t3@7tWsMKT~T%`XW6>h?0uD!%N1pDNKq;uvOSZH4q5m=A9du8 zWxM3th9dbF|J?tyE1eYO&@;E#(2Rd>3Cj-bgMZ>O*=7Ifdfe2x?EZ^!b$79c52IuH zKX;aW(G8u`Ym@hRW2Py&$-7ix+$NX(fGc&MUOLBn>ufJ7U&<<%3{loJ@{^Uxlh3*3 zChtvv`}kXo5@kP#Yc8&qedx^_7yJnoXBlu8bO3kv%)4(!A2GJ( z7#DQ}ckA>!04T;9W3Eibm>0}Vr#oWs5JQ2#Mw9vN;j%^yE*K)De~qON*Qf527RmASayee8I+ z^U0W^{4f=>qUCkFavQH_;!o20 zRS*Ct%~}?Ds1=1Fb)l{5vbw~AXbtWZ^nd2YkfN^}I}%L-t*8&&>pe+ba6?;LTSUW> z!)_bVEj|V{rbH(sG1G6JTshjWq8akwgo`Iyd zROO-}GIYb+qwSH|jv+e}rwKg_i>bj}w1a|<6`<{dzyXK0y+!>;@%z`0rfxs2+K$4I zoq<-H8syR^?n8BI@LqOvy1*B8FRBI5A>4*`s=;gm=Z<+%3DtS?C>5Y6odflx$J@5% zz=2HtPgjm)McpkSr7dS2I0O^bi>MtyWtAxUMUP=zH(m}Xr!r$G`lD{d!=scT8zaE( z>zTMbxYb)0*kkjay^72P>TGIFmj9@G?w8u;z;`zP(SB;#=7esJz$^vu*;Ig9Q*Hw^ zZk+^gsdfN=q?a(Po!;!)uE2I^WV1~T?M10t$*)u*y*L)pf~Vk76|KOd*Dj&Kah$Y~ zm5_Y#eDI((Mo0ameW;CGWNX$&E{${!G&%w?hXy?_Upz{Q-f3gk2hde3{V8(gPny@` z(lDq5xEQs=9$4zz6dAcFV`OCvbTD=!E2~LE|HmaGl`2|DB&YD5(RR%aOL0{R@=$IS znIn?bf4NeLbmugw&cYvbCpjoK%|zDv183>z-`uK^Kr(tbGP&`jt6`Y-H7 z(~9pwF*P1qwx=!U`^{qL<5#Ad^k0$+1+cO@rBcicNh*^UL4|DU4NzWu1~5Qj@p^DY zWjIl35|i`vKxWLzQ5Jok9t|(CE;Ii8PvEJ2J5Vb6T%&z~r9CfF=5Z7EFyO{~SV}LT z*3=!|-dI^#Ddyx@cs-hM{!-ZWZYdll!%VF)Sv#8ZvG{;&t9HToC|OVR(DFQO9|jJ% zv?kUJG;69IFhNv@4taa9!41^_TjpJV!Q@3@MGoc${ZI7P?>VxKhQD&MU*(G-<*o7; zLQ0~})P{7^M+}KEe9w;94(#3Ygmj$6ktNyo( z?ev85ULW>aA0_b(0HbA|LG)%&*Z|rpt{z++xKe>_IV~__b{s#p;y^ZLRpd#J2bVx` z34~L;qqRxs6!f@J$9}+}D2u$kx4|Dc(ifG8{O2CXFFKjTKPJI$u( z_1MftXDRx*Pf2G^2TAY@hzG@HG-0|p7YtS`!|^OY^lm-#Q|QJ69kdDMwTW>`4NPJB zz$O)KUNSK=VtD;wscA=0^B(=?;0<=nI;??de2I4`YQ z4bGx6(bP4)$*0208Vts-GoVgShw|=VXLouvJAZ6;?qzhoARS6}E=jNU^`%0BPeC;i z$IEm97z;6NUta)c|E{t0j7#t5-9TQhORx5M1iC9y=*;27jJ%l`=NK5Lr+4+PC&s(e zt0~?4rgRq@ox|x+Qo6jep1ra>GZr}<=vWItp=Bo1BWLJ z6Vz`63Y1@Bd8{ngvHTlZZejUCSspM1<-xK%iRCk8c@fK}%5ojc-DLTDmfI+j!!rmr zt$!!WQ(68}mY-vJC(2?vR;=Un7fT^$RS`$M;N|G;Hr$0Sg(a#h<%Gmc3JpLjFpGJ< ze(qo_ENU=}I_}k8pEnr0x?xS;v!=vKa6)F?XN18FoIx1r>_y*RLFw$NLskH1$(`^W z-vCE+5|%?O?m5%n!|siR*WN`zZuecgp<4FhNCGmSzIC3&#^ZqNpwa#luMUr^fI2uL zM~gm;dSTrzqt2i{f_0mXIDY4Aq3 z+fWyOz=GP+ck_HKeGP9-hV8^>0K}^8_s|xPq7o}&)c|ZtqSUTRL-N#|+%?NHfaQ`DpV79|HSB;do;4<|`UWBv8(g|j!-nT>17vetgb)a|* zhEMT!i#b`K8nEtW>JQU}C9AM^#O5V%AbSn9BUHq3J20&m*Tn8D+flYPl_tIn9rC%f zmcY7fEb@X`68~&!FW44TczMi80f4=Yz5XIGoWpV*U;vR(n)sXsqT)OSUdfUEa<_a% z>&1?G-$~p!2^`+Ss_Di)f)+dKuTLZ`fx`>Ng{H{P4Dg_zdkB9XuFVtXRH;81>Z9n&Q-jg#ma~;g{qHTf zcihq+mfE8q?$_LPw(^#+vR%?57L$PjFaW)})EaD4YI_m+{2$udY71GKjgnf^sNadJ zf3u&(TiM8IuTNwNdlW^#3Z=k0*F^4@AlO*eEr-w?Y*{6AxU5|jfE4|@U0`?N_0Y3( z1>_ZVYqGEj8r}nc3hE$1Zf|40+|~(I$FA^ztu6f_PupBf9s6ha^XZEo+>ie~ME&5- zvxSX;tp4C+P`DV#^*Wf9{zs~!VM;GW|Mr|dfd7K`e^WuC`)Rzt=_?dh??mNEl?b!n7+&Ox397*dei@ax!1#ln1d-qaxv#i$x?E-x8qbqW$Ke($BzFg z(?3BALVSttg#G0(@SFWbqmPoFWnE#m#fgrRp2l% z$KzJKIr>`|BH$w<`lEmrM9%`IDV2#YVJ5keNgg) zFQgK26g}f|sQQ8TFg}<5llHvmW)zRk!65u=PhZ?`$4~^;H3r*ST};+7J5aa|SC(pO{@|TIZ#}{LH1r8C@!Zxc+Xhf zCzQBK+i-Y){ZVKAkv;=A;kd4U*h5tk7j@XQM0FF}Ty7cp7kR`Bb9~$_^0MR%g z3VKSgi6O31;KIp!>}W`KHw?EIT(dsyE;06Q6Rym|Lw5;y$gNt313U`ZFqtf4^N=Yv z57i}N~_Q@dE2>59v=xM>U z2ox&5;rbu%;igNA4Lof7M*CN&ZSF}p@dK0_vo74E8Y|%afD050B;Gdy#m@*o_G;px ziglb~V)s`?+p4BI5Vb^+)TDG6X{8Yd#lQh~WSp>-0tETMUSue_jdU-7kwuF0@wejW z#ekmYTwQ{TFsOOXTB@(&r~>)tI#=^jEX%dLXgS%yQJslDfnu?Yc)PA8ZQ;KI#g&59 z(&{V#RK0{7Xjcth1N7<=8~$>8nTso9tD&<|s1o?dUKRUPlf^h(nKDKFX5&Hi7n=^M zJzzJu+lsp_xEtrm!re~X?ZVw8Pp*E?bnXCr&Olq1_ZMQncdM)!9%xhN6&+NwxYbmz zb+*7lcx}Zsaiv*5iMEv1dQhDJb4&a(P`p$)jr{)|_@FwdPRJe4fW?^bX+(DfS~Gm- z3ZZRv)k(2Yrr?QO(XypA)q*lxhKUjM4w0q>^}zkQVF-<)L)1}X?IUjm!q_k|=)PFW zCKKziObKNR!=?UdxSL>qT!I9`#ww05Lx195#2*AjJhs3l(#{~Yw~K$aL-Bq;BJr)( zJf%`>7d={2QyGG(kzUFtA}n<#)~d6kr4GzVag^gGmz1W=7QvOw$Qg-G5LfDh_3oeA z_P{z1_K;ln^p~MO(C}!D`g~FJomNYnT0=w`w%ykn$v~JG3t8x1K0v@KBzCLX2a!j~ zCaCu5fNIMg|Wuvjx!;n_{?G zZP&q0v2AO%1j2a4nFYTjL z1nE$tC4O|MQO1u<4SZv0;5uqxm-aO^F#fyeA|UDHaB3ZBVNg;Fvu$ev;6g++lM$+f zT{vw9tf2RpBam>!r$a3uoz%%dLnq7H>tumibGc$D#V3^VUb<46sFaEWc~B`=8)Ybh zPC-vTZfV>-?vQ6_Iy-HBWGL-c?7iY!z)Ws=O< zE@Gx`5YPsB^n1`&8h?yfEUo!Q>$PZ2?2ayE^b9>StuR*@FhhwUa&f55JIX(g(>MB? z)Z~;ayx`(*zEOxS3si8cf3>2z$UwCpAcV`efMkM1@;-UGt;h(v5VQc9ka9Ha1*d_c8a+aXmA{EGG`~Q zfd>0wOiM94?N~_3EdM3_4iwQ!o7C*wcfsQJ0h;r$-1ZjdVZuL!n1LtowLR{GGGH8T zLLzkKS^X1iG2VzSP^O!*t-5;@0zfX-Rjc%Kx-Fu zX@hHvZ$FpO-vL{o^-NKJp{Q3wSBScaYA6qd(!^<{(YZE0hl>Uao^eS7b%TI*OkFt! zSdUzWT}!|(*+#x6Yp0$5Nh+PF;2LrZii&R9T+ogx*L4}MQL z3W>=Wf|4~HfcTxzxd?Fw>g)lyfT_5*$nPdj;B(()k-r%72adS$Ogq@%b%Zwh-h~nf z$tR4VC&>-R3xRReEq7qcf=%DQ5gga1%el*pD|2L3Y7rCT*St0{TEy%Vv-QP0Ip<&x zf!3~S@B=KyX3LUPOLsN+K3cTz;$Pqb(-4DLjKQZ6OY2-xh%fkflzV#9V}C}On;?et z*lLI;E$Ow@P`xN~a;Ty8_-hppb1D`2Khz*ScXX6>tb|^Tu?m9KD9knbv=PL2wLwHo zR`CqxtvhJ)3+BULL+%AZ{Nidf z-fY`y;rq`M1CI&DrxW|_@xhcFx2$jk_B-OgKm|3w9%={_^RWb;^NAo}#X9;N;h^;E zengA~>?(=4Sl$zR#UUKyulGXW1{;!rS|fJU9z7~=PmlhAGH6>OCl70YcgWIu(7?Wd z62z_qSrIVpe0|p;(feHVEzqx$efta1qT}FD#z|8N8cy#~r~uvaptV9=3z;EdVp?X! z)cHi178;nY_!&%>SuwpSZ;t0_k%7t4A*LdX-XN+O*8#@W!z(c=hIL1$M(>N0(z zq%hKy+5@SxApHPbGjSbcYT+S+;=?n976#St&H{n~^?O~m=8Q7&q;)jVj}ELWf>!tt zHcOu;DV+kqZ2en#qY6rl$p9obaY+1a!4d=05=JN4cKj9eFiUE1(Z|59FfEtW;gN53 z9!}fBp{=5Q%KhFrhg%!x@NmPo;qGsV<}G%Ic{f?m+)8VM9TeV%XMM|YdLY0y3&5W- zcdb0^w6twNTlJH&6Wx&Le9!{$0s$UP1L$&oN{R&lNJ_!u7)jBr$;QbR!0U-g9?>%9 zc10`!Du>hGqS&s(=+1fK>oU4rUot z35Nx9Y^;3-CSmR}99DToqX)@bSubFnlMIV-b&_RSBGa-&wpogo!+ft9kLbUZr?rx& z7%qAU8l$oj&^HBiT-{5l7Sa0OUe!yvP(=LI#UG>9is3yAhEjpSJACawQMrnm(VD({ zUVWs&zXPdEYG?)fIy|3{+Vj9Euu~{2k{gdAEVHjXMR8FY#m_Ai?*ec&pOsiyI%EMT zCx9DgUMs*+3&3Ck6e5x+01&<+KV5z;=ABT>Nd%Yx62(kao`ng;8#;J#CyU~>Qk@mrHmFM6VK+R2$paZRkG$vLX1j5+=BbHWn_p;xOKGo zyqFAuV++Ofo!OgyD?SLlEy#ND*5doDV%-F>lJkn> zpUH$C_HIINoSd>4xm`8|f-s|Sj(GYi$o~l#wfboG zM6J1gw{u`~w5(HsmKh4ZI>G#$rF8)VJ-7skoad?@qcW=KNR?>`EO8XrSSxY zORJx@%?mc8j)O7(_SfirakKPbGm6ps9I+9!RK>{_?AS6HEGPTl6ICXnYPXJ3Qv9ra zocyRuX2LW}lU&YW?RItXb3kN@UrqLybA`w9e*_M)M?w&R51@q#p2Sv1GN;YY2Yr~w zUxcJd%tIu-#ZPjAT9o^WMfgHsPgm{;U`|u+AXB-Cs)}{A3v8MZWk!lynvMJj+~6>y z5H@n1*!HPGnjFVt+Nl265~ZzoT>xoz7-)20atu41@)|mPw&0jBEXq&a=2$wkitU~n zyx-{XyBc)Zoz}r)>G1pSEi-@jtL^t5=UV_TvI0)VWHX0=EL>y(%&`JaO#{5t0(js% z3+Y<`c>Mk{3;WA#%l`5Tb_cz27Bo%{PQxmg5T4U$2qQ6oIJ%f8Ep_31+6Yc#I6R6_ zPQRORB7+^RB_`o~xzGyV=|#>o8g66*tvcD@yFTXhU?~Jb>^C^R!u@mHP@}{}N|2MI zB5rSjamAd}xwsAR7S<|Geilxq{tjske3l}S6E;yL;;&g&&E6y>y$u)r45``R^}xLL zZt_Ww)oxkHOYv{5S3@5I5)OI%D3Rr`dh)nY_BCB0iU=3sB&&u_0al!E)zFzJXuFb8 z-BjF&QQZa^z@UN<+%W?fxJ9H#1~3pVGA1WSYMzDvi5PHtZ8aDn3E1Yq_3t}CLdru*_HZ8 zE|XLRtK%(Vym*T{CBCQq?N;12IY~=deG`?2w}zDX`>0LEw-8%-2lod1zSG|#^x7rn z_@wOUYOYO-YK6$&i7|myEHlnqh~KKVr53e$4sxD&@1(*;Kw;G-1*7bNby@T{RPnFj z384?Nug{O;dEK8`TWG1B&e|o!Pc2&YxA#V@lnahyMFfvxP70p@5rQ>BZ>k1w^ni~ww@l+VI9ihn|ZF5)36)+6==>0Zxxu_$` z>6o&JQoI0^$Sz;XV`{JO0T zF<$f$A(Uw5)nUgw7!?tJ%?Q$++TavId(~xASL3hVUF1H|Y zT+mLOv1v#gYOqJgNL&^qXSPRjQW_Gc8l2WKlEyf8=0bbX<@wN__KkReARo)Bp&969 zM&D8nJ5GCaIfkyBlG43Rgrrn$|t%uA8B2X@rD1~<$vjQb9%3S>{V~+m8ost(rU_jnqdzdOV~qajxmn89SCt7#s|@SX6-SmUt~u0 zi9v%`d1JhY>K6reX8?H-0``S?odi&YN}bXy-BWnJ2iz2ORu}ldP?Nap9G^z!uzGYr zblDe}Y{J`xEBdpmsxFwvuHsIO&t%!pX{baWu&w4BGV!^nOQs9pkcE=}+mM9!G^~?ZO~a*1q+(?XA7)^AzX^!`fd?gL%LLGtq!~Fb(Ef3k=;A zXU&u}n4uOJ&TYbsNQ3DCnE2J;zhWKNJh7ci?b_s;e|s&L-MDx+0w&*`CJ$6=SM^ci z+=Pi$ZdkJ#{3o_J^alSN%aj|usfqhQ(Nisq_rUSej?k~)nm(fS9OJ$O_u`e?OId+k zX@LiI&%Iy{tJAZn(zjD~Sl$OUeWa5D z;gi5H8JL7?ptZZY&ote^bK#WEsH zorATV`VRV68>$&z3)N7$18~q=4cV0VnJAg4#W)yBYNfOmw6VRg zq+@tkVgg$=x;YK_aRT$*SreH0GS&Zd8u0A|Zmdhk_`O!Q?v=(dQ5b z&NtU^!pR5BrW5`(x<;6CA)Ig?oN%tBmMfibIo=5f&%b5!#c;y2+)bj?IdN(Sls?`K z^%`5h3XsMEESLd*d&@0TM}}<$b2AarnU)}l=$l@U5Oc!ZK%n2_SAx0FqMaA>dEByw z;tkNV%+BZ<6V+7wv_>MRs3jPm&ZZ%+eluUPo}i_mHca{rVprd%-)4; zNgrV8U9d+i{lOhDKnxt7F^knR+gv?qCG=r)(SO>Hq=Mng))sm}gI2_eEvySLJ6`Fl zgcni;CiPL2{Us?ooYN%+6ZAwzY(VJX%3W=3;f2%CF}&Sj4==oxrG>PDir8cex@*V` z@YsOIKd+NR4UXX?Gen(1VuneAn~$&H0YD5(EqQXPq1P!SES$djc-!6hDc5p#2v?8; zuH}!TN0Ycy<9rB9Ro;KOSXn|YI3-CS<`>ogsp8*R7!m`R8u`n>kagrw2R)N_F-)+I zv(sP>eUgF^(gP+V4Q8tahB}}x-US}5v|hHraJCR;O&ZLDfQgU#7kn-RL97ziC{quX zI!@$U=30D2Su$jH7{4@lkJ~^cIrZgYDR>-)@#YTcLfEl6^;4>;Xb__~F11)_m{j*j zT<}C81!IW8GC?{dAN`rA*U??VGew7CE(?=;jkA2J zv6iQY)eNDSdC@!Rb5HzcJzun!8Fs>)hdXF8FmmiX5dDWY)H6YREk|*++k*C~e-~}7 zcx$)veMrUp!{7txsOwOK-tANT`4?6(-GSXhrGDmTDBg&JmHr)$bd~yrh>Ga(1NieL zo@rEyl(v|7(+*~@n6Y`MI4_}MEst=kJ>W5(iM@5qNuE)!tfe8Y&SS%+qJb$F{3p|o zhzzp!!K~B&HrP!3aCrK&;>-(-r`~{I-j)7gnVDdf%piz4#hZZ=4Noij86O$(NrY|@ z6BHDji;Pl}lfi0Rld~2VrODaMi}qbY1iHx)A6Mr4EK)lHiDMQZT zi|@)|@?MD@nn!EVPkj#+%mKJ8`f3op03|*^Lf%C3AbjEf{02$ajoif0gt&abdyA97 zM`)2RJqYY}B5O)KXW-6mCho-ZDe}KaC;uobPC#B{9D@9TQ70mQU3>BYfjvonnGnrN z{;%(lKL~3|f7;KG7io$hfBOl^??j75dPjTmrx@gsW(n`^hRQr}F#{r#Lu^&!v1e0wA0jXaIg#H z5>^EEK+PQiN!Ol z)Pq^};_Vo3XSF7;XE?8ih`qP7RjhEof})^~K~P6N)KLK0kOo^sm6YhCg?#Zd;XVxE zu7Q%`XW?GFyAh^z(JO4x>uqcK3_5-`TULU8kLV@#=tO(q8+$wtbxdCHKmk=u^)ydp z)_l-A5e^9yvsF=pHxqI>CaeYq&lo;fSxX<(LGs#I0CLo=DWR`!!>fYK>ckj?t~3Cw zX`c@hfLWacxXb{srhVQ;0A_O%;5P<)YqJa zcchKcvF6EMLo;B`Dee46I3=RDCZ#?FELGe95#X=^U`NXiY=a*vPC>QfV}(Skq5`z^YR<8UT0~GPoN6csr75#f8g2fehX|vHP_J?eA zppk^Fa$W{b<2^0CtYTELSAp#1VlHYr+t1UQ$_xNz&!z)}2*8DhFVHgol54>|gYhvE zWB9Epn-c(B#T-w(yV8%Ctcjq{V#%r%iKE@tx7Uyr>KkNwCAJ%3c&w*Y%$Ow2UUNk> zTQ~%3PUdGEO74L15~a7F$(1z`lR1O(;k49xb7|u3jyqb@Et}FhE|VRx3s%)7N9ZpNY9a~J2-!ZwPLo8)O;DSR zP9`aJ$rT)P3!l~m$7|Baoh8U^0Fh*}sTF(xz}uyj4vIKLS}E0uH6bbQRS0FKQahXO z6se{!wokxZD{AMSFtc^dg=xeJPC)Fl??5bJB(mOO<=v{;=|DHFk?E?Dr7a>Q6`{mP zu;qQ3ohpWqnW=~eGKG_IykY2q{bM`Ho`R92Bn;c41m0Q!AEJ1rQ1Msb32MdAw$_V4JPckuh7vC$R5AOI z4(bvJM@zJ(nU328vu8dc=f=BQf26*3kdB7^jM3Mcahl7%OkQMPbZ5>E^!XSx#Y{si4EM9qn)|4su~sC%9(>CjCBj%~-wK$-{8}b}#wQ!g6*);K z^Z^u_Se9OUHhRbB&|h-0Ea{gN&&tLV91Aai#79iwDuk;|oK96(9)JqmNjcw;~a&1Nz@!fJxu3 zF5!n7EIf#;N`r^1zyq@?8={VhYK=qWO{z5;3Y)!ABzGJql=o{OHI^Z!RSLGiL|32z zhKOT5b0;||Z-SQ6nQp|QF5W+`6&gDGO*%9tQu7NJ_?Rh5RZJvg|Hr{I$HU9`X|ytMN_wM}fg=aZo}j(1@wh=3*?~tf zJ|gHg%v^*-PN6Z_w-gA2V|)!FuCxq~=lS|95@cw zMBytJzb&~*?=c?YoJCg9#ST!g zl&jW^;+Mj*BMTV%M=2|^fDbBA%8V>v)E_0WV`TaqGBoA{tfEom!D7JbekGH_CZLVJ+w5+c zxvwH}B0ig6D<-o3I=yfStQO}1e%Y+z08cM+kz#^~a24@Zlq{ZJB=%eYUgP-iqRf@y z>LAI8#xW!_m5uFp6{2zG7ie6-M(}*kQhDA^M}Gx?%w2-WFEZAj&mbfF-Hv`Dh{=ca zteA8HL{1`-87R{MYT3hBQ{JKm+Ukdm?5qr|uOd5(S$85@0vaK-Y8Z@vF6o%*wO^)~ z7P(ml(}Rh9SN)e=k??`6Hikj72gx*xw>X=4z>~*cp`cxFU`s7C*60pQHHd^ablrol zR`3-7x55Zjg3DEa!`_gIZ`=*tMM`Po`4>{PdKOWCNGXgq`ru zt~LhN;U~uWG_m@vSec3=Cdu(ET(%Fuj{>*@_TJ#8Kw33F2Vk*kk(Og1gDPJ8Mf*G< z#oHqy@_A(bS8yH&@Oavjh~LQH6Gx-c;nmBbbiyWm@nt8^|OH4o^1z~W%>=@1ZRVlWZFl0fqd0=}%;kJi&jKpt2Vq{f`(FZRJ(vZMa3)4SdK^Iz( zhy=Zqf`+FdLG<_naH2I7<4C$%U4X_I$Me)GcV-? z7Juz-bl_X19k97+WzyoWZg24-At>l+#IGR=JLvd8q=Oa*{KZy`jrM?n@a{Uyn|2Qm&q?iFK7;VWjzIdq);fE+)`2OV8 z5aqG@{bxiovjThi4BQgQ*j6|6v3uuVr)B8pAK$iNXs5HcU7=+J_=Rqw(0fo9je6HK z*s1||?z63KNTa%PXD!Qm1Z#O1-=&nF_SWykt%k||5R@Yrn^Kwj4ky1BMj);u)Xyu+rsRuWmB4gcJxjR-WP{m3GV)>D)``wCfEk#Mzly%qtWT_#8BrF>YH%)i0`>by-FK0oJ_6mxvwJsm4_xN5MY;=-Hu}!h1ObDv z!A7LiQ9b$Lq4vc2w4%OHSfVySc4`y&glFWu$o-CA4msmqhu9ttJ9ygB2eKo>A&qaZ zcCAOd%pH)g6l<4xBE#KUsaw0&Ek$=~6FiAMl4O#|7E@=Vs2qM8On%6FK#bajvSE#g zyZ4%X@==>M!C}klF#-sYRK-0r(Wyx1-@pcMdGewpv+zyD=Ek2X9v!c3## zd60LI;`;?gvE4UI@Y%%ZaNC-*K{^q&e1IuOuD`@rc1!U!;K5Em%;uf}EX`)= z#`ZXg3w=FEC=t0e)4ETGmP#1ry;pHm68s8-Fkucr7_vvil!N_i4ZqCcNQSn~%hM}< z#CKFnU3On{q%;>Z;iJgdJPkj0)|_}xOhz$ev`)z679TgJ-C_)4ak@u4l!$vF5W9CyASr6g`|!ma@y3_TM!@k;zjep3P8 z4ApRt2zBsNTG1{FD+>~n*T(}#j-I{gD?=_mrv8XMql5kryo*5Xln_@UnE{`n!F=al>0I^DD=Elpwx`@p}}sZv%T; z5g5-EnvOZT0tj2XuEIhB^{xxibhmEX^lyGuRSot7(k6Ur{&XTIgZN5XiFmC>{6HTv z-jeT}L2t z!$!L*efy!9al^_peS1)tFswYwx1FjQR-Wy94~5CY%5!~9DA0$F2DZ>f@1G(Q#0oIl zjhm+<<$2mwVqD$OQo=#FQ5SkWWe>Qcr@w*|NDGJ8F5G2ac zFphRm2LD;2ct>LBZUH(su9IP;M8Do^Cu0$X*k|*Xl_&;AeENs4(lN|(v zP`x5!9dJbl;qx$?g;ZPBm36BG;~(R@v3;;^=r2OCYR&dh>dHgBeO%nu)$ew7!M;v> zzC<`CK~P=E^@yHC{32mLu-`jUo)y~abHbt%Es+vZa={>&A==f}NKV4C8MIc6wy2D_t-t)h#RT{$n4Z4h|VK}6v_M)z5E_M z+`d|akv_zbim!V(E9MMhg%UfXaJdcYgYIObL#FK*#U-=tqyh(P7*%S@CZ}fZ9AEr5L}6IOda8N}$D7&8zR^X!h2qgKya~#{TDri|vi= zYMx_FyDr}LU0yn_%ima|*5s4{e|U?34`LzC5h&N~cDOe9_qK#Z3n2V=qPB4b6ec;Y z-;dw>%fNS!w&;Rym%4Dh?eZBN%Qcf)END@$6J>#80q# zy^BRyS+_-RY)2>!`w6A(P6_>cT1>f{>vSQlnv!-hrG@M=d8xsq&g#;j$-9*~2T<9ixtf$5}BS=Ww^xLcXCLDJ!+U7s4+=b3hW#NEmqsugs2Y4jX>b}{Hha%SUi1&+*k zA3Mnx>moUGk}c@O8+Lj{G(DMYN_ApgB>7jyO`-4JT0#6nC)S4>xXd*m{EZ*Y?|m8KS1AZ_Vn+A5(TJQQ(q6)fW9qe zU-$^(Pc*dSq7GcdUjUMJwe_rh2(?^{>EGcKpM-Mt^B%-E>)PV81XbaIF!>zYTJhc! zr=g>k`rNiV+;C`XzZ_2Au=tCOlS}b-b~QiCI*u?t^NAAw;fLCcQj>EeOHEEc$hV1y z#(`FKUXLa}r@7K3e4A2|*e{wA_(46oGR4*q%@ocy`VePKQ^o7}tHdfe$bvuxRV_;d zU};LMV!0@4_4P;W9HmS1N&>B&=l-?HNzH=^Dhn4fj7teGTq!`0SFw$TR!TmpRrK?- z&6fkkH_=jU_))sk(MDrMZh`KAwVyr=$`#D^n zXdUBvG9q#D^e#9}0R|A)A&Be50Q`!86C7>Na`k=j}^|XE1oo

`_@cqAl>vZD!3vmfALke<`MUaX6`DeVW!Y_pzKby#NsmDB7 z9P}Ze!gCZ(8M|f?(D=zHLgYmq2q@)+xRQmpdoqh0-YbeS)!^-*5`PTd9!Cbk;OAHA z{UakBCE5tbYVyFAaQ(KuF0nEaCR4%;&m64{$AMH`yn|q4h+t!&DD(!`4Bu~}c@hkf zHL!j@yt=w_Y(MOD1jE_Lr-7NMHKlG(mbb#_ogzOP_P?2Vz~h-9#)E`3fQ}YE8_nyulGI75e1YD3Is$vwCw{$R*7Nze+=$#=)>& zU)o!7_2Nz;&eRH%wIpoP#MBxXk7;35+=z^>=HF1=+*{M_>NJ>dmiJYdT6<$jye=9} zJC2GR<-{M4Z;-6s2QlOj$8*7D+7kyJncQNYMY@X}_R(B#PT=V2-r3k>w|hVkuJ`Z3 z`<`1gu@lEB3`(u$=38!)G4|M=clDkYXzk|hkKZ`*y=CkJU1CR<_`7j?sM#$mp2qQ& zd%bO~_}!<6v}S$qPl#xQBROJ6e-t}>e?p=Sh0^uH|X7EyU{h# zDCq@`+Pt^mBdBVSjvo;gPt+l?07h_D-z4YjsAUEUi+(VKKsw~A9Z+t<3F0|{Y|t;syJJX7D$a_DfA2Qe zj<6_(7tqmrO2DY?NHjZ2I@)|X=J-gk;NR>@tnzPmBwmYVVj79&@O*KeIZI4@`shq1 zj5EN9&Dv)?)=YW;4{AE0U4-}eSTJKALoCB#qxfm-&~hjpw|-FJgm%+z)!>t|)-+^q zcYm=sCaA$hXu+g(i>1jCq6k=+khk)H(a_B~2oY2@_z1Nm0nOz_4e?NFRJLDf-o_hg zkXx-8o8#Z>R)c)tfM^9KqT;;{r(zsH58*5%mbtqe(eZ8CRdS(|Oz+jU$d%3n&6A)r zGYL92GqhC=-w4_=UZ2ajV^E`)!tHM9vO^p1NIYUPl4pWj z7_os75n4CfIzVMJQHc-Db}T<0`l~f9SUE~GEFEu(TRHI!op`T05gXS!qGOMdjRgI* zA(5egu?}rZ#U4dDrr_77WK^ZgCT*-EzLs9oP%y*%Q1DKxg6%}eD6!dgJi>-{2>Da- z2643}dzrNDEN^Kv`v+mjA7qd-IeXNV1+Q~zX<`;dp5U-%j6?V{Zy9H{OC0pO^E?{A z6lh)DX^06OVQ(07A!=lapJ|aLPqK76N=76bLG0u0eFAp*$J_fDS=)iV7okOr7=P&A zn7Dq!>iL^%$2DsWfm*SdQbYS8xETZA77^}|gZmv4lhm4kK;nicHiMIrjCt^v#3C!G z5E^kM3-M9L1ghVifuEdmV^>GzMnpsa`BD3X?UuuK8{k?+ZM-M#{@V>`U77YueO4Q)DKxeQlfB5L`y1c~HJ zbkf26UwMgN48#7n#>j4r(M9O+zf!4dFLAt!(J6YIEoXTz>`3-#C1<9(@=-BaAEo>e zKdZ1?l#?|6J?5J+KfjW5@knwmGMPlyeV#1sWJ%2IEhveZsx`_WlubO*OPr4H)yyqd zR|d~7f%_L{0vwJ8U>h|m>e$K6F}WGmGUqDZ));HhqN1R;sVMB*$=+x4IModgIi_e5 zOJbc`vw#6D6WvEh6-fM@V4t-jw@I`m{$vEh9BP8@LJzeI(9PX=PQ{=E)gwq?`IAf)&ZlQ_2W zIKdiyA9gJ9A7CNqg)ZKcjV^NA9T!#vzlMOUx$}<403F`o0g<|B9?rXB?-zcEJ|*c( zn5L)JJXVJ~|Gs@;QQ$)-x3_1s0DZ*X&c8WJwulX!%XUahGh zuFTA^xW-F=4#;5u^#)KXG#ppk-TK8^r~3O-4K4A5(1X7}*QFNmyPAgE@w6af?rI3< zutj`=g4XJQwPw>=vuLgL2|LZTQ9d6FhZ$*x%`T$NcJy%UK0HwPZ<((HFB7KQO{7B1 zgpSM?lz(voaOIeoIJV@}Nz6Y1WSi|6r&#^oF6O+5kAvB@lhym*n;NJ7AEt&d{f+q5 z?GCMd{Ap9oIszb&=MkYS{JV2hiNjs?g9Dij@u{W$Yf zgc`(mRvb~sdF-6`JO0A)=h3o@`2MN*jF$aoo<3x5N4tChhACVgKfG3T9iJHn4)C{2 z-56~?Fgflqf87fmhd2#*@e&7I?=!g9d+wlCiIuGkOM>!PItUkjwAp)dptY~}`sFt7 z45)AypeEwMZ4maSct1zY=cuV~b>cZZKOC0x8E)(LBUXYLmf>o~)3{Gj!_djL`X3$j z``}Q;Q#re9L;X?sY@4e&@v@2Uap2oW1bRl|u|V+w6cwcP7W1g6czdCBH>&)_8$?5w zR~)Y9_zX<2SCqsLMq~U2+@rh)An~hFmVy*hQg3!~6)&bRF~FpR*@s^5pvEH1+qi8n zOcQGU55jCF0x8V*Xb|*IoB*I`hnxF0ptwmCLk-^Baq|goTtYdxp^h*> z98<`2cxzt_SFgR|ZX55aTTlkxA+C>t-PzN3c9KGOL19bZO+X+hpvZ+@c7k6wh|%wm z4t~qXspAU$<6$C6;y0Q|3wIn;TnL5>4Zsz1a`3ry$DGZq7u`q`-Nf)W3H70wOtP8Z zR&!L-FdN6>G>Q}|WS})=$e+tf*oFs=be?yzTGPPLh4uf)S#k*RI6@vf^T`N{6P^WKT z-X2tm%{xTr&qc(~75<{ToHsebs<-yt0&av=Zw+nnHXB4Y1d9E_?KK7Ze-GA=CEk3N z-j6y*B#U8j4_=Y3tETCS?{(nq35uEp!^(tVafqvE%}mVj&KrvT%$0bzGU`1`sg%a$ z-_siIPNxBeImcmM#c~1&^TN3uab}noAIgNg(;20vM|{1gqy+kxIJd;PB+F)DV9$$Y z>fA&wER6gJl)#p@L>-zgS2=b2))`707qJ zmqPwC{QCaZF~3LJ^ZN|>U1Xq~f}hoe_PI@Gdz26|5fyBo2aLqZmeE!c=YkzQiw zgPd}94@laq?0+$+qw6kV@UYd+{I_E=$Kr?nNx#G;Y5+3MHcT8&ALXY;=9iKr___`2cv zoFDd|SR}C5&NNMpc9sL{pbN3K(Sfp!fit$rjV(>CK1~%lQWcwq)q8tLRWt}^;!}qw zzDJb8hx{=rW1m!p1$+w9Ln$(Li`}*Q!`RbJ(L_bDP{9@GaE)5CjxL!l?OEy9>fkAj zg%dkSbKz{}Zn2{on^4Jvn)rjcH`EIe>K6O3T+^r%r{dj#%v$a~^pSLKt!=(5uvN+A z*mRzEkvVxk65fE`CUe_v(5B?WntcsxXsrD9-)3z`Ef*cVjeZ7LTsW+WX(wOvF%Mao z>_g<^VUc&KHEJJ3N=i_h85zr;u@EWj&DzXtY%P=dm&OqhZ&@-s8;gH%IP@AR&Eu9p zWoDg&xr<{wI1jxoOAako- zx7xLX^+)^Qx1k+=Tiw7Wt>vw*G=m=ouGjR#@%p27O|Nh5GZ3GIdKm5N@xH*oW1{aC zWcAe_>of3MZi7L-Vc3Q_#RE2l#myK`r}{lOt(AG4^}92>)U)K^<6}|kjKoQn9G))q z+GX%_F7c|t!1}iYXB!TGO}ZOWbhS+b8`hGqfgftEhrgD5AGPou(^?^8=RkcI{Ln9Z z*B|LK5UU6BB@ycz);y=%fGyCHBYqR?Ui)BR(^^9Z-;h#^h0?)+4Q~oc|AhSC;7jyJ z3=Pyr9h$99iw~?PqCis@Xo0<{gM*}m1tmqv89$6!L`rWOl)mbKQc9+;B&AkzA}I}w zX-7cGDJikHprm2v==F38GJHT1~eK+Laj6}&d&x! z$_x4a0p5VLDO!16tYi>Wjo8y z0t+0Qu=h&LLE$h8m5I9zVrP-qB_QUTjJA>#A@DC~Kg@n*L_7B)K&-+oZ{`h2!+#s$ z@&NIOz<;uV|2*RF3jAKD*wp}lVcx*~12Vi_44D$2n@sj6k~qclZUGhB+|7U=B}v-m zy=9U#SUU_)lX%e}bUF!5ry!4@&pn`FVqYlmRp7NjKIWMP5hIu7BK_GZoYBArZEW7` z?9fIvI8jKSOYHG0Q3jsD5|2=%L6z?#iYyH|3TF|YM16*d+UKn0SXodrMjtDcsQGXO zsNctE87!LOpGDOF6za)Rd|eo!4l+x_5V3q-UwF8SAS2EnFH0=^eHsHx{0a8tdE;Re zP)UYO)SKZ?kvT+|w29GkXTNdOJ086*(nVGJtNgvJrR`UuWZ1WYKA; zE3|pf;S1H?kxiu;w#e8boaJ*PrG%DR=R`6iC|_5d&`_(`{^x8iOb}kaXEHMH}5I zR^kzOv`rOz#Y363*lxVjzRiFW{ME@7jNiKDhi3An^j%R>)jfyXzc>-T#1diF& z1$2dR62qkzXkhf+owi+Iabzr0-3=YoQVi)7G%ptlvTV7aj3J+ z`z6xE+`g0X*Y3;5Ux%*%e_g&p{LS)h6!pVI{Rsa)m$x>$5H_HQIhput^f&oB4K>je z{f$?@grx=ppolkX2;e|ToYxbzg!%!-nRpF>c;*wtZ-r?HNu!zh#sjCW}6zi;CN7REIM_nf6l28KS-r(x?TVR@$LYoGwN0xK&=|$IbykA4bfj? zf6#6yBIQ$QD?Fy`?6OUpFjZ(%xc2sgK(2r!$PJ=I@qpr zG*))17!=Si+y5X4`OnMoBTlUz1V~=67UsY%%iB@ z3kyYkw5Ufi`48R4G3Q|1h2!F%qAQ3^O+1v={aqqu_rzMWMKVI-@CM%d=JgI8f(`%{ zIA)7-LjVipS7h;~%R*c#j`>B^!=g+h^c9<^B#(#6E-dnU&ySQ{IQ3AoAx41&*<`$& zVv5nNFmXOykN2$=ZHZsuFp(ILQb1x|S|5XV^s(dBr#ycCz=2us;)<|BNqmL><13Wt zEG4lw!tie`U-GZ>c8xh-Ghe1`DzPa|*u9jJp!${^Y9MvbN*3uyGo*y){AAWmlt4SR{}>2 ze%!;H?C8xM=43#@iyUpQi)XmSdq(mx55ASbc7fyLn1B)G?UW@_QYb>&=+ha8A(vJz zem=yJx-Vfwhde?n*^&FRw3*n`XYlON84Kt=uHaT*CPNhd{Z6c!_k15}!^dMW(#z_D zTf9SyI^VNbZWWb_@vY@jv5w-)0dkj@XfhZ2y?8amZ2bpNEF+4g^}$Wv>Y|K$x)j;( zeuDb%G^kUN?Vd`r*GuS?m@n6()F(dpa_tVgfvemGp>V=lN6 zL{L+dlno&kp)QA55A}`m#R2gYOT+uU%m7H#AvVEL)c2t^QG=fwszSsdvBn%o=rB8S zS%EgTKz<^numAoG#d`+#ZK17|somrs&e}}}zL{?rhqgj~@2O3t4x9gehuv3$5;xhuC&Y{B6bF9aXGn*49IFeLI6*o=UcnrfW)H`or$A_p9HGogxaPB}Ud|MxHyJH0YAMV~h zKC0sSAHSR34I5aviwznzNW`@TMVo4@NlkPiAw)q8f{K+YK2f!_McCz`Dr~$7E*M2iW*4dPRPPZhDXJXGEF`hZ#?1WSJJ_nCV)n*_T{jhy3}0A;nHq9TNkb;0{G*|WCth# zL5Oe4^N-Ouy-oH&k14yowb4OnwTKl7nBIqqqLX_SbbmM#BF;$fZHdT5 zf)7Kp(W_^)Rt8v})n9zsj177!0|O@pId14l%YG0*iU6?J9`ZZSL=LEI{A7*9`=}TN z?hyp3SD(R*d>PP&whH~zQg8Qb{Uyh1!jzDqL1O^006jMc99mciehWz|PtW4yPwy?@jFnlaDk(SLp+I!oQn;o?Ukd$Gv43@bstU9{wL z$X?U%2H!YMpXevSPX>J9_%*aBT;@nPO&_-Y6aDi3520O=);}a^m-b(dcep9)zY3vl zoCO%Yy$K;dcHa)>Q)n4ks3|PeEu={b=?R?HyI%k*BA}`Sx6A$O6&SyRqhH~8lmY`r zd{B&P10sBsxkm-kmx?+NPGF9t=oTjn6T-EwKAy34@+MF79F3d4w= zqA(iR@0&p`e=!m&7PP#8fizhPxYQqznhf+8ASu=O)Hk)%qA3vH#%Uk^-J_gy5-s`C3FXLSf4ei@@0^q z{6h?nZl$$l>cdf?Dti6}KN{KUCx=jR`SLU@((30>S8ICr-CIc8NH$1UebHOeqd z2@k`Jsn*CqMf|>BU_o>YM&p9ZDzqbhhL=VpRqXo1of=e7LT=`DvAAiZy`Z9`;>TF4 zABB(f6(heH_C?1XD5ENpQ>i_!LOXUPK)*=PTKM1i`V9ff*2IGYe(KJJBkdyf9i#31 zo^Yq`oISE@+@I>-f&rx8_AK)1V)D_OM5U3QBr1^dx|4_#b*rB|3J-W9pCX4!UkdT2 zClaNNGE&YQ#EzAI0W)&1+^Agwb@6l5L=ZT99a8^j=Tc6Dzw6n(2Y@9iL+#c*b@dmdgo1bLpQ7 zE*|#4$P^o*=Xx4njPLYBeZkLd7?Jy;F9pN!#{%_7W`7q_FCC`IdEmRyTv(SwjX(hr z!g<&78NMHhLXoI)1&>%I)S2E!Xm9tK?WYR{aG81bQkDH)gJrBw>R+S5V*X-P7h4yXV2#;Ytrim%vY413>{@fa`3M#h zzfR!(1V|zm^JOvc7kp8@VHE1Q7a4ZzIRy1oQgAS}e~AZfEm}B%b*)Vkl>(|CK$$p! z@%=XHOt7|uRPF;rdX)>BwZ&#lNoF~VHMS@GZeyiK){;?wFo0(VP75}@5IqcQ{`goA zH6>ZK+z&ZhEnJ0$Xkm@p59KH)qOTa`fx!ruGu_rnu}u*!Yx1AkC?UBc--Gw5_drC2 zu2BZNP3r&rSuJIH!g9Xt1^=NT{k9S~%ZQNIe-6TTXwTmWTMYTH8znNCNHUPk{4?+_ zUQiLvy1F;3`~uEbSqu#i8n}SVWwFo!=81^s=`&HfoI`S}Wu$Y&dk|UbTtR}uNACg; z%H*Ol=AcLM)|?u$>>-3LOPLcU1pWL3U`f{I9sTm! zER}Bu4rE({n6-Jwki0gBwRQQp;ud{4vDgPkJkZR~`LR*Kyc*9vvK%dTnS!aWxGVk^ z&JT5TM$ZKniIThAqt*|;gm|d0PBXT78Lc)mth?4D8Wee zgeawhw*3@g!Q+Ke;E|mhsnaG0T;4ftvArAf!6*3tAvq?tB*EZd`yK5Y-|<%C;_Cpm zCBCEG{~plnNj?6x#@UwYi3H?d@>XKpxxXd8Z^#^YlHBZW8@ih`$+{+H zNY*toz{bFXVxG6czXa%o_o2rHQ*$?hIr&LA^!)1?aKaHS90?0nKP6lxq}1!{QK*m; zRz2jLYE0;A6mWWEM|UWyEM&X-re04T>-0}mcgvLi39EqrLDGRcDD5Ie^Oe;{qK#YH zQexDxjQ!Q9AlbE;e|O8S*yR|tHR#ISrX@g^X{qpy2*b>@j{QrRWED_++Rh9y<>fw!xuSO%ZU|J4vcJb-=#;;%mpOf`k z6HtL$wM_1Nv}VM>ydML~Y=+&cQ4xWTLyKZlHAnwV3+{}?4o6^f4E87eqhsmLjK+R! zXz|cy7vYVquikL7rH^^v*B69+`F|k=7xryKkQjTM{-?Ih@9l0bisqPYUaNQ>~l8xF3 zKtr}dR&*2gfw7A-3>~JhI~j@Pu{{ZSMg5ymdN41vd@qya{d_Nzous5zT%ft z5v0$7G<<*({>iTp7f;XY<5TXqIics=XxarqX%uUN~9iE zxnPl~K@Zx$`6JbX_QRE8v_j>bqObS_se;GmZF|~qI&|NV6MUbM2<96n1V1BDOy^y_ zeyLwa@|ilR8Al-+rrl&AxAo(GYT={&!| z%NKT@$I*G_{1Af}CadeaQ;Qf4=}E70WSt9(8QJZW9GiFS*~BAmLr%!=K`!UrA=kzz zZy)G3ntFDKyQD+>2pvMe(?6HKa+3+KT6zBqk~Q^={d6;8A3+!QEh9I?L^lF_zYz7- z>{HE+t-imp{rHDRwjlqUHg*`oa)5w!Ew@(+^#w;_)q^1*dHboaqucGLQmbK$gW)gs zFPu(cWs{dW?QVLb4z{Fj8G`~cVt%8L@~&cn}DC?#d3kJBLUB*7~naYFLiEi<$) zhO=>-#W<%3zyCqMUbY0t#&_mK`<}QDD9fwClML{ebPGV)uZwLvbMX(AE^EroPM!>`#R^6*Jjchv#yeV^$D+nN);W*i#yg(JW9y=fK)fg;5HE5C zVhs3DY znmseVubu-uHr4)Nd@nk&NUP;562ZT+Ql$?_eZ(c${-)Bk`oen!=&nR2i}AEz9ouF+ zEl9^+*H@UVdVFtA^zQgxZ}i^yUSIV7`WIrqiSLWY9&lD_iQs9@LI4wIzS&49cq%X( z35JuY*~q$kUURGgu>>MAb^$7&H%vz3+E3QMsW(zhy4Zerc_-z6tVr5ref3G#+Luq# z|Lvi;QKO0LVEplNjjqQf&LcWOpZRaJ`l}pmhGMgL5wUa`qq&yVSHdaQQofz#kKp$f zh++a+>`i?Q1jjX}85BEHuK9?U{cmtVIC;j5AiA+^2t%!)AcW=QQCLVi5Wq6!Sesdh z1*B4k4Pvpl&S4wMfUr{lbgcY)B|mR9fjD(FDUE}I$OtpuTwbUUa6Y$F@e0Q0#%vWyNcLvj^ui3$4d}U$urN6gw*8EI zqm&Ynx?8?Z$2<$oBSnd@X@fEAn&$m}u+$s9#7sA*ea7~4NcvO9-{Tu9% zV>PD^lVDbbDQ*$^&M+WUtgnpX@))>bau7m3pT4qR*~ig~xNs+4`igY(2Y%yikNJ_Y z$Fup}&2MwPqZ@nmXnAw0FI5~hx#qrpQ`Q!ng&XpwZ}72WPBV*vm8dcxsu#jEw#Zl) z#&LZYt0m@M)7F2t&*RxE9^g;~^ToV<<{Rcm{cgtdKJ!)c9|y;MdUyo!?}2*R$*U`}E&^>hXM>RraUm8&1iu;O5Ru%|3N&cC)IP$%~T?UNP63s1LrI zbZDRc{(Bq)S~~}a8@>G}{Tk2BGxgzZUjJk~^D>3yo%~0V9sGkMG9RqOz@gEg^V|Eg zqq52w=zeBNewajKSC z2lz!_$GiwVyv(hf=HOlkH8Zi|d34oib=$O@*jjKjxLV`^oSMfUA2Ejb7_qlyL!cP2 zG~z(G0T6m6hVdc6pU*`9Fb+lhwfaY7o{AjMQBU4eLO#+fuRurxUK4$Pp{@8SSh;B5Xt0{i%?=wXz%VZK z>>Ain)@=Uc=)cW6&0McPx+RDn!k)>tlE-;nk7e>$*G#REu^IQ_p)~I4j3ARq=b<|o zw-jK1nV#p2TX1Bkp&U|SK&!~~ z-MeIana8-L2og0{Z!j+C&>w9NHoq4{p+zV(jOJgmeXnMnUrY@MZX@ZVFS-Eb;oQ>} zX!4ErsnL+pJ|lJ#_A%6SVH?KwzQ$hYhd6nND@JT4bJ--RNYu<6;qHjzAAWQ_9Ac`?7 zmQemf?!vN<&8`II0~@c=}XAci;(#uUUW z?wgBi-}Ht{F*uj5gIsc=!0%{&FTW1^)tZ*K7PArV$AQC7um=?6<*+LASf}ysG*9#f zWyr7Be**M(`)8@+{k1000f1M^turU&vM(IfKBNq>MS z7@KYGGPe1a)nFlI^ew__S!==>c}%_MXnDKRXJg=+6{UdQ1MKk%tk-w}J|kF}0cQVQ z$R-nNx(_}xUhvsl)dg;P!yFJE3gK^b;7XW=8`!u46!;Y%5)d~^GvA$y@9ZSuzUa1u zxwkppw{E*o3{qLJIh|9tT`0C4$6&p_KMBpWYCTh_fx2{Nx8 zz0-#tA3(DQ!H+}6y8ISJm6+w!EOzSwN$gO@XF!?b(Ae^Ymu0AI|1LwBi%FT)$mp{- zJW~WT(ow{ywzvsTw2%m7I^FSTovco`;fp(64m}Eg47d-)qgOe-EqW;y*g{1dVc6lt zsfOt3phi%O9s@InBk``+a}YWd)Eg+upUCco7Gm#OpT3n4eX$o@Iy4E!_D?9p%6I^3 zeVy^Jwb|}59)2xtd&Kc=^u;k9?vc7T=}8KiBY?~RHt__vDK9YFR10mF7FvH<3vk%v z;_!mP;XM`XRKed>@HZ8_qJmZxI7mO8S_b`73pgjm{Xp5;nf>62B3RZoCl`x5{*&F3 zV9g1TG?C(3kjN^8a}N%{>-FSD)*uo0u-XVF3T5}rD8H>UHWRn;fYDebPl*J!zY{m{ z`W{E)c9L7y?I6LVUO0&gahm+eJ6Irj;aD4AE@j`v3?4@c-S-FYB_QjJafrr2CHRzL zF3ht~2f|umzK3V|GJCIF4CB3s>}+X#sS-KMQ2J7qgcIpF1p)(*17@YCt6_F4uX-e$Be*?MRx4h6p`rk$cIv_8C}5^n{S)NEA;VOVP41%ug}({@e&P=? z19}$mQe)zn#1foTQDjnD1~r_hv%x~1tNgBR!CPl>{^Q_aF-yxW9{&K$FYNl?`yyy) z-7t_9h+{wz>G!JEK(AX5D#+^6wdPyHUxNUOPHpFyZxN>qVUpM~0~>^(1F~%GMV3s7 zpv&JfbTQw;%+SMFP3Qx`@Ss>+d~BJn zmL#|=+}ei23JN%D)Y;kFxp#W@dyb(BSJXMyK_}XdW^8yLBG#wf&pIsN2^#`v;N#`0*rH{a}PV76oXWRlfyjIqU_3SZud#{swOL{8k zDTSsf&8jETTs?6?sP?0~H@)KkmTLOaM6^OP&tL~oM+?w^iMSn1;)71BN3gx-RTL^Dvaa6!KKNOed;Mz8aAOc*S8q06t-%8 zoFX~%;p@WoP+?|l1&GoaszQkbejGktV2?Nr})+Ova8AxsRlWrA=)==PY zCfQY1+YjQa`>ip&DSNT=m3v7tP-sI+Ce|UEk5%hz6OXV5YS!K(8mo!lN!xTE(Z1PT zBf2kKZMq|xE5g}VI2E1uo$OA29VcT7+Y6nhLZBHfUJih9DlPgGca$e^d_rAM?8e-L z7`dO=KDXD{^jjF3aEhy@l8Wr1N%DewcSa-D7@jpRQzW5y01ADE?%&w6uZGENN)~96m(wiZKkZIoJMjA;kd+#+){MGtOUVEJx*$=RB?GQ#!z-Y~J z2R2569JWIwc&%1v|H7R`8shi5xAPl2o zP6D|DZroO5a0=Q7$NK9hA(TO^*HhEt!fUfPr|5xG*3vVqONuxFg{%uoxPJtm z4hr}ZaJv8jViSNi+XdZaqPbw{bK}R7GnUEK*B18 zyb!UXI5`fRR%jczoxw9P`B@TIpV$@VTM)&Y-^q~;FUwcVW}tc!?vywn@NtOUf~4Q% z=0O^CQ~69s&+$1e!!a`g1&W>+f=Ve(?K6!u6z*MIJ}-?lt@qdmz2fhwvHwJ7?5hU4 z&WV4}K`7u-?-H~L;slwjrivgsO_MLxR$X(jUf&n7phrlmknc6ed41`Th;wIv+U#yx zq9)kg(TlBW4(|(aYKIdnJ`S<&q)VH1F%2T~t?@FDNG_KoXqhHhW^!?$85#$(+=z(5 zjKpfrF>KF#jCqA)F2Qd~S2=jlE0a|Xfq?cZdi^PURkfv|fjUnm)g51yg--xS8vsu2 zl)2gYF6C2f>fC5``y$l*9uYXm7fyA$eNoW-9^oD23$H4px+n|VeBpGshKsW!D&-`x z&Gi+3Q;B|+crj~3qB!m6GQvu_(*^CiK1Kr&5wwe98(@Y3h>y@&Vq<17pk#KVA(J&l zkHuOu09z3N?6FmCZzm5DLl=Biq?U@f-3-EptQgCi3AxE#CoZm!cLITnq!K4*`I}m}MjFHu_+;Ug?``WvL1QxWF1k0cD`O zL}go}BiUP=HPCnr5+(VYN%rNl)jMRB6+QI>)HzaXBa89u@{e`Pw|u`q@!b>+Kw*$I zigMO~Y!vL*6P0Y@)GO$aSZ|qon%^x*NViWtqoSJM3FYl~uzX0OWHlpL{zAP2%R9Q3 z(onT2qT_ls2+%!=-WUYUv4FxlMS$e!WG^u% z6e1`!C(snB+?)_b5HTmv4yekUKy#WJb3!qKapr`Q){&(gXRRYe!6O@;pr<=Or}DR9 z@QS(?g)*aUN*9@=kTge8+dIr0Re)fGIf|;DVsjKLP-2cEyDc?G4YSS*%66+YDrEXH zu+8=6*3^^#Bz!7jdaLr-2&6)*<4mS9DCk*ZLuN1oB{dTekVDp`HwEF3%5)DKcI6q5 zJUxd}_iBtd1dbsWM^r~nfts}?!mU6;xX3D1n**Ro>nI`7AwWI@RRbv~J9(_&JnapoI=lg6RouTQ6wO{lo24 zkja+PSgL~e-{}j_MfK42MzEtH9M&Jqbax5NmtijxEYu?#c^wt<<0q~;K+`C3=9E0t5j@FiO zC(qn!wi^2av##B}mWPue24KP7>Vq>c9!|z9*3aCS^(OmZAuqQC>GcLPIo+b+7<3C! z`pfQz+;)bWH+Otq);8Ny3CFvbiina8cHg-T*dgdquj zL|*W)+RVa+JfLyktBXft=awKH6BK-D$&MS=U$5fy+pIGWgHpl*(o{rC#nYFd55Vpx zcDz%05P|bgYH@oJqcB}adoNrwl8CI>uJD9an<}BveV5@iA zI}yz*J8i8I-;M8rGeiQXfI*B>Q}&#{_M`xYAO*tID|d|6o+fveIy}SK5aKSYmGAt;|~aDua;T}I0sCF!-E@;CS9f?4j6ObA-%6nA76dti-9anF$EToD#GHI zkcO(#KscY`T|o>7q*;U5kq-(l!xV_F%MO<85nfqXt-^xOcFTMIr~j5P^pXmLzeh-J zfb!X3EH_R@H4;Vwsze|IPW~{`+=1P%B7P3y7IDwu6ebgSRtnY3)GLG&q4f8~LF#7e zhN)G-S|xCKbLcB!tqOAx56MJ;7E3i^JFBjOrE1X7>5D=@68Lp1S~v!#AneCiDeh@I z_gSUpwiHGY5fBt2+BAJewp@UNm7E8)J2*fW3Mf}4SX9J4p?09YZQkrE5!w+VlYHb z?Z@6yx{i|mZiS~{3me5fZ5X?fyA9nn&iw}X3ej{qc;h|?Gm$%;6h5!7s?+R?eV zpipu?l`xU6{`#DB+RAnre)__#C?v5sjtLCXc465k3v$fY%y!juh350H$1>l8`l!IZ z%x$|4l8T#U=Ejp@KS*Y@8J?zx5b38zkdGvpk$S65R({9#QkUs5}8On(fLg!5LlBy@Eh7_1Y#*@WDqf?eIe_z%7aDcB+T!crdq7k+?X zm$}hgs|=%{^639CC5mWn-CBwiW?KuToqY3kY1I^}0L|$#%5HLo6W0W-K~&8$O5L6o z-UFa(v-_`R00S#I#UK*5D>GbTVrpXM#AMnTre1Bth!R245tL4KrhlTAB`ER56_mi$ z0f5WMD_S7&9Awfb0Fij?KP9zJN8I70FQ6#yVA6L=p}6zH#Jcwjz_{4)VHleF^}^Bc zVFq3~XFOR8;}TTOLdv@fNeOy2LIr+*>#3SmA1=a|93G6i8_9?w7j&cI@l&|NMTsUvan)tp`L_zLTQI}Gt-YjDYzD(uLu;f)FZZ& zKw>d=w%;c!bn*)vq~?MI_$JT!rm%&d9H05*gPsd%>^bxV(E=t*CH8|Djj&0?G8=|v z+8iD&f|(PaZ9gqkHSDjA#K)il7D1Q<++mL3vU(`A(0E!UOuaAIx4+YV3~v#>jpSRa)X;wUKpQF3aYD9>F2y9l zhh*2NR1g?QrAnMiLDvtXRjJf-tOzT_X@mgyPW-NP8f+fIv!JxlZ#R(wBY|tOs$cF_ z|8(SH_2+MP`)6i|Z9m~e#(Y!~D#OU}H)^AYJpSds!3PWJ6psTUA~EAZ@6 zsMnSTGn~x~#Mk}@$aEdabWF$o&h%XL2ShAqL>?mSyYbe}w|%&_$zG;liFj5M0n=-RWT>jv;7Y$)@h~|^)sI%*jj<)edm|>{w%c*HkRuilk>U6ZytFV; z(y!5XCT$dsLQG@TnI7x}%a(C~gdB=UG**Baj>NO7GtHLd0Cf5a&MjV|62UeX2}z93 z5mg>5#2kz~=oz@?Moz3k1s2jyo)W$e_HX+fOO6Jv9F=jlUJntJG~+0v=4J-MAi51V zB(6I-qZ+{5R1>6m8*K#79j9BT5KkO{XrO$(CrQ%l^~d3v%pHpr{^;kol(p*#_CB-y zfj#>Gx-|U|a+>?nHrvg-h(Q`pVpCW}n1@oW$%L16LX6*b%gT$)~>?jbck{%2M;sh0g7| zlVzGh$_UQ}bBq3$=RNCzaEaM!zJ{gy%$G37{LWce{>gE(y~@fZU|(XkkAQvl|8d)Q zK>X(L>6%=`R<1>HPbezo9>YjY!CtieK3M!Pv~WJ?#m*gyt1##&mOybm!%cvwu%kbN zK4uHQV()RkVl_??W`VXvBtC^s%3(xEEHTltv+!xr7O1Ta`tDHOl78uHv12$HU2_Wg z>zF!pW3TxMv=#dUy74RuIgE+e^0IYN5Zh9?735g9=_D513>ld$l*g{kS*oew5RZG7 z=nKYrA3ho;AP%WQ8g}$ZsqpRs34?72MM_0cMhkDqNF9MaJ{hD?REaQpa776Ei4qIa zg?Mr#gNv0SBqJF>5yE_sKSU7%98sNL#lds1sFN{(cD%bgDW`yxQ%TCt7jz@#x-UUW z4w&mmQq+&9U^q-B<2^&t2C#_kB)!JWkaYTglcdjKj{DLi&Hs`lJr|_vMpE}IG{cEc zZ~JVoN94|DC@%>%-PI)2^Y^xM#MTAcq6FQ$)O`IJ9|i?9Y_aQ{A^c-UH#F0Hqf0Ti zyCqv6*P`@s=4qG&E`=+7v_udC9^;E+D^dk%D?gm7zXg-Y0SpFkf++Db&of?>Yg-v5 zla0GsyOd0}&yEAI0OgKps`F+De~(eviehISbIY2h^j^<%(4u>u_CUP&^!L>0vMXRZ zW>SiWLs89qPDEKNQDl)#TPTfru~0;IO6-0{`L9V$Y?@MMh%UJxzu|*ey38lhv2ALK zJIP5q3H=Terlese#tl*5L`*(oKHlqbx`kTy0i7`*Na`OSLpoUB8*9~x3$roj-O&F-nW2UZq(j^bUnB5;=2%uZmDNmLqy!b8YIE0z;hMXQg7^z|Lk$ zPA1C1VX;p}!C|zk`zi0lVTaeJA*TSJ@+w-tF^sPBIrB&#-6MM`h7Ci}GU|-ke)xsg^)jVX%JMW zvkeX5ZZN5SCmL$NT#)tQ`&NV|c5iq4@b!az_|2{o-?wVH8~^t1h(9O#PsXDopgNtK z?2Ym{>g7`%*%MLc6OY1nIQu<5`=D$?ERFqPexyz}O9$cn72zg)Zf6@ijan&vCe&c# z+XtxvH_dxgAvJSK7~2ZY4%;CKKpW5=U(1J?;~q;n46MmvJGZW-2;(37;-$t-flipS zbIz4b>Nn>?Ol^w2WmN_dCH6V!KkLXGrorUKY_a`<1l@@8gv=KMKe-F|{0wkfj&uY5 zFuc&%&hdD;Is%pcBKReO{Ha~=k8|NyVW9LVpaumXj@>)_#h?{kvQTfCZM-+ z^j6m@QUA-0STVz0~5jR%+VWRB|! zbGmuSaQ54y;Uc-C1WYdV{vAj9yKy2Z3NfDww;s}9 zPf+&+_rb-H&OO12{J886;`Zm$S9Rs^cgx{8PvyP$O{AB4COf+rw1V-OEie-7q@Rgur%GeY>KSi%*= z7+@7CYZ14E0myhk$R%1R})hZF?cVY3SwB(ahIB{bMWUtEsm^l?gfbk{coM zm1STtHPF>A7=XueOsltq&|9UEKDmvMY)uebVd^FVz8 zAGI|gQxD~3Vq}%Mb`3|W%!~9aem7`|&3L`xK|Gjy;96XvU6^A|QMYTg%k5f9X_MD= zyO#I~;2u6|YOHmR(qJ1u2iI+s2rc0!t8FQ<(O1^e;A)&Th;P=YQm)|s!ty9Hxmvnz zhIz@6Ra#=g=rxqb(o@hK+;WT$bJ7=4^4HjXEfAj6oX#Z)-jBZFR46M^`aPL~jixGU zUpOS0lYNIdUk44%wN9=Gb{=B=xsV<72R_RXODP@tn@KR{y`SV}PPv6&YkCRf88GeG;#GoEltmy;FlV4sNyB z5|jwG?BQ?#)*^S7>}1c0)_?L9B>XTVM_FG2jo^f3Iogj0Y13G5Tl#Be`t ze)P$o%@_Az)A3jmJp5A-JQtlQKqU`j`XUBHy~A0g7XhvsJw0q0T;{pkUxSTtPpr0! zW3~E;+_S(Eh)~xqsvROV;@cx}2rR&I?mdsYaBdee&tM~`j)20_ST|j$gpHX(Wb7O? z{neTrRZ33us7&myUa66@jDNv!vG31BKZ$7jU1v$ga>}7iM6b@=@33LoshBMa9S?C- z_n5C)bBl3v@&)l7zUU9}P-Py8-)i$>c!RE~!Q*-7nHLuz9BW<-f9e_lhu4>$X z%ZcfYJO8fub{#gciTnvHx~BSoDGHs&7n^J!vg2ms9XZ-oZ4zy{@2Jnex7LlDffa81NR&Sp-+|&$ zr=Pi$xYwaX8rp2l0@cnCI*8H*sq_i;)J`G6zdZ@!n2Q+#n?VWx*SH(qeQzGAE=zPB@a%xZ_5 zAe+NW)}p-{C+R2!<>tWFx;oG}rpCajW*Oq+1FC{)sh}$bNd=qD^|74gK&8f*ALuv# zrC=P7_Vd;;tA03b+BA@4WAk1fYHc5avFsb(obZ{RCi9Kq%}#oAN6yLMmpBL?*w}bM zl{Ma{64FR8*W)t^PawW$)9{UuuD1Db-^(S{R&_z5#&Z}s&$Gq{4Ym60sk2n8vVU-p{i(pe0x)TFZ3T-le{BBPsF&1-{e^k^)1J~H8>K! z3RK~1`S3{R!#?t%{g%?4ysm;aIBu;S-?$kJ#)=fjcg%=)6j54=z^H&8>R;reM}zC} zqxQcT-{+ZAU^M5hCjZ~OW13kzz}~9z+MCYJj)k-B>6n40K&qY!Y55w=MAtz;o~y5% z9-hIymMC_EjO?)xL2Y=b%#sjJv zC&6!h|2f|-59&rea+UXu-dNr*b~?cx*I0c)WAkb7qdjkWebc<_;?u@22!Dh~`vR}GG7g@D#mkvEr#1F0FK9dhLpBNhcs3V zs8UlK5wpP#rLgh1`*$^2AQ3Fjn+@OiGI!|pZy;M~o8GXI7B3_4>;7``6m(P+C*Pj?b{FPZ5~RjtB&&3zZuI7FW^(}#fBw| zjos@!u>zR$VJj4%@!6iX6XQT}SrcyRw9vF@&Z$`MTm$9xb(r4|sNu&Rybi}D#nw-Y z%};wZ^zbv$&@l95L;sP#Z0JdY(a;+j+eY*)KT%(lkmx2j+iQaC1HL>yyr3^cU$(ox z=7L=5#2N4Jljg7`#?&Uq)N1xMc$z>yJi)#+ev4O&!s&OFUKL(oW7fcfT`93}!#-vv z4)~kRc$k&9KE7avHn(rQ^w4YuCQVVg__7 zvMw)9+*At%dg`Hb(1w+@Kwn!b_gYm>TFM(A;j{w3p32&R6DKiWJMtxN8pg*M9<9m( zYht0fF|RpRo47o{-f%gh53>AoZ_ZNJ@Q!zH&ca7a39F|qM&&S~<6hc3!c#eH;KUIu zc@}cpiy+GfPz0QVRRW*%0iK!%QrMH{sE_l&KYumKVzmkqATAV(+CA zM<>;*2d~6^?=_>fctr#frN?y(l=Smevp+tNkGV< zK5O>|X4M!w`u3HuIclsYIcgmKpC9KfWVk>FP1lsH%BeaU zWbmPFx_L4~+VxEy{3-quD|GgvhB$jsLuD@t)=E3Qw$(VQD)FvjzGVvJfRh4w(g9?27t}oqd>)!FjGe9p_48aGW-X|NQ_F(doK>9R zCcavz@Qa|dh)gppeaULv|5WYOELainl4)2;<@C%=y9FN%G^M*+5>$z%JDdFr?pm=oO3pIqbp1Q zSjnLLn^oA8MhCqA6HK6;dn0MN%TzK;Ki1W6EU3nuCk?Z! zuM2%9p_c%<{fOd!>a?Z9`^MJxW^&L>eFL@9pR0ubR8MRG9tPC>0=;DbxJ3}7Gvlib zQ{csz`Y?cNgOSGST7AXESl30OZ-Tq?ZG0}}`Io!T1tHkC*iRepj|15v5JRdUhSUIR zEx1@~wIW`%&@z701=_q2lGK@SWJ7moNjSE)Q$7N1I?z-X!I?}lSCcgiUZ=tax4tQQ z!)gu(yw|Gt@2}=~!Fxo#pZD}Fcwddh3?nD1$TOav&q!=MGxBT|Sp*$mZLp}Z5;dBL z`V~b7pniNC%lgI6k@Qd|Jp|PmI(~K@z5ct1=}w2h445bn=@tF)PeGnPk+oL|QN|XF z<=-lxgsrrQzH%aTP4i(EGa;vRlD8`MLACu}*(cEvj)W2&o`_;857uA)A?Wi7s&NK} zRI+k>ZnE-%9AjM-_OX(c7k1jONJeJ32F^(M#YTK#|1G|C@%w}wx8f={f5y#JDP8_N26Z21;?Ux+Ts=q{sz~{Z&eOd-moF&DR)eDfN6BZqCd2OZ#P#~c-L54Yzu@YqsY^)mSv)i(%jIoFc`?igN z8Q?-+5&9mg@dq>p#@leSB~k6eP!a1SFk#Zhr#YF1{yx097;H&6sck z_#(Az3THY12=G+^0U%48hm_Q+QC%9XcYq8uTE*08{r$4;8m(9M;QEE{^0NyG&=8a{ zVY^zb62=~cC!RC&QKg{F1l^H5pO^)I{HsX^C8)-3 za3q2mjzkc{>Ji7bFuq`|P|GO-I#36n958&ncT@-t?d`YV zdTlHIzt&^p!~(-arzpT7dO}0L=60*f$ZMVDsgjT{dqQzUj7iA}0yU zwxIO2-a%6O)|mr`w|K7z!EL3z5u^q=HmCrL4mu>xY~EO4N?AC}2M(u$_lvbRc0u6! zsGYCMolpwxF0PN-4~D{^EEGaO;qs8>wKqv)+b^mB3te8Eo0;v{y73y>Gnoo`HdQTN zPM}xmHMX$z!oHon6ulTEy7>DTQ^HyMTAu^Ayy%glq++ncz=VsUi-Y^-FL==FD? zAH_R%=?(Yd!I;ZN#4$HKJJwpQ>Ik(xBHj^#0-+-w`)MmvHJpNDAGE(=%nfLuw6A7O8kv1DaMirquaOk+E$*YB7FR6_7mMxe+N?^R92eg zW;9z17}+k5=B*8xudm@b1{#2!?+mdEogsFK`El0}Q%18CKl{iiQ^S(SGO?@@y|mT+ zYMNwDC#<~Ipi64@AKb4XRoY9t2GNH;`#}(wjuW9=r74n^xBQ7mtp$U@9?zzPf~72s zP%0id38U#MRWBQEZoRQ%EyQCSp(2%`#*kZO!N#CVL^M$}UwwViMfmzC=j$EDO=z;e zw^mA%*_-1XkHr4f$`t@kuf{triapTkrFdaKo%M15ct>$G-+{0MYFSLJJD@PK@4;TL z7JUZ;JA|maAk(Q#Vt$2g3Vk}Qb!p%$X8Q=k&Wu)sZr3?z*UL3IRHHi!7xQ`afKoQ2 zIKa-b+Qq&DBEJnhyIJnylG|?~?$h6a-HpJv!}9R0xy3u0<{bx|bXS}wY&w5>jbhiS zF%kxUuR`=8cULHE1x-dl^o&;uGrLmHf~ml&6yC^iI&c8DXUff%6NFWoTfOSMwNx7_Z7jGv z8drGFqCr&8)*GIeXSTXt|1zGltd!Hf^fQQYS0t(}Mu5L_u%&7)0&8f&;*oEewH!5X zvX*Pc!+&S-m@#KK;VfDfI6F?0?J(*KsEAq>!9(~d0Yy#|Lfd;}-pG6X$ zqp9^&>-uJ%a4gONOIJnEulh{$q>+7W0V(DwK;5orc?Asg8+=!#uAnGo7U`hkg3H zX!^|37E9l6<6R0uU&*Gyk_k|P?Lp$<7*K;#9;N{`$oebPIkl=4Crr-9XCl9X5|m+u zCDNle9v0B7?i6rE_-BjtN4>CzRv$u7mkV#m6uTlZAMlJ^V$>3&U7u5FZrr#R_o?zQ z{Sk@$7o3e-+_1IuE?m*nEoKQ~!n@#?J&uRX9nEmdz9SH56PX)F??TQ43I>-{7e5)> zh8QUtau_L8$*V77m9Fo9^AR1M2Y&NiZ54m^oXC}g zXM@#$7_Q?>l)R8Axe=bgpdy2sIuSg#dArZ5n1nr2@9q2Fzv+I>I+yOg0_LmDokQ5G z(a2b5_)^WsRcRny7Tx zWXfvtH&zA7HDb^+S6+rKDy%swYr=upiE7f02iQ;0G1+@5+@eA8tED=yII~~0j02>z z@20jg{Tb2pnMr-cFNzSWZs|qC(7`@MwHDA31ui7-3FBJmCJu9Jp~fB?ot!|x=P zI&!yg?|eQd-yO`?Wxr;&q%L~!cr7&(Kl%zIPXVug4`}Ht?jDF&h}hdvuE8_f;dWdd zp0`0?@x&mee5_LPnesU#%)D3N2M|tKNqx8OCjl_oi~D|hRzW`Z0)@Me&MK&&TS0@f z3MxEEL5S8;&A-ePB<~yW4zv}yqSypBBK$ljHo|@M#D*zKtl5q3u^OU~CJxuu%;xJ1 zyxPA>eG_2pms2AV$bFdhOXv%wCi;7vhfH8uS^{`Q7y>75Q$#x+&&@jmd2Q27gIPdF zYJuWAJW(IAk2Thn;%3W(ES-K{d*G$hToun%m^AkSSmW6Xzb+KdsZdW$$B@X>=}1+l zA*j>2paMD`YQf0(GaN(O+(V;3YQllhzr#VFJc_-w2?fK`Yg6>GgH_>hA)S2+s&E~u z;MnC&3KwDUV$4s0M`BzXaR&#J(E)k#Wrz#<9kgj`z@>=n&PIo4vED%GnylzI%|^SQ z*Gg~H8*GUS==D4Bkf_~F01ID}=TGpJzHozNI0D&?_9OLsnsHlQ1CNr`zo0k#S<;S? zwBww#Upi@bAxzZ1Wpo^^FI*_kYXNWe{6y`eMn}KdvlF#{HaZ5){)y3k<$~)IwVxXu z<@zEoFz*cC8#xzdc^%%^1fx9&Y!kIW~MD1Tdl-bWGYL_wmYohiStjJSF`^*K)1@WKGc?d|CoOh3gYhDAvJ{B&+YpnL! zcj0yU?l!&_Rrj$Cyw;W1MbBv5(v*VQr3r?l>>@`_!l5-p`MaV#CT}m_kM<{(|ibK*YGvQr|*Cn%j`LsXbch*1{=Ma(s3x%G@eu9BX5KS-LvO_#W;< z06Hmd%=wNr? z`UnCgnJ*@%e~T{^GMA-Rwu4Z2B4T4Z_8-jVAMFZT_fg8I+o4O7QQBzATWdHtY zNzke-gk$VnAi^xOHtT`H|T=uv58Lr9y!wAn~gC2`(OO<~+sD*xwhe$KVX zA7NT`CO>E6)Ck6%)&o8#Q{)dZ?Z`}iPPeJgq18|4bipS(Si~t7?h3Xs?VWutKAeP8 zFEMTt;!xpTE%JYvlQ3d0uUF%+nXXjpvGH3{m}#t#~xri=q=23^Ce$xSR;?|E~lg=4M(RT|fP# zdB^s*YpZgX*#5SX)n#v0%BE%3R%I)`*JP_QVQ7T4 z_BjTbg685y3R=j-|4u=7lXPYqE)&)?*5B|FV}5M%;rcw*MP72?MGFEGcZ}1voKld^(QNRI_%DKl9he2 z$=VNT1LDcb8a$up!^V#{Sy>xSR$l5$3L8|LW$6}x#D`j9qW`&lc$QUdW|jLQR-AGYhgISS{JO zi|kSlUPaPx<2~VnOZl9{a$(TIrt7xr;KQb3*@`hsM73{}(a~rAEAAqqW2}pEZqgvi z1Cs`CBEB(ca3Swcir61d8o78wK(?Hdl+{f`(&&pfPtsuPARq_+IBAgO;*I?Ev!p?W z>P;Hto`6Yqi8S)YSkfRfL|T!GY(H`BT1HX$~L?>#=V>DR^ck8xrN zp({4z#IoinR3qH01TN=kaCmXIiXRLK%6z1~7RMe~6j_`TA? zk&#GPgM`#jtln5M{!+WamFo-e%s5sNY9%3(F^r9*$^iTck#Z_`fjb8ibEj)V#fJu0NzuOg zije_KrXxKq%T3vs(gYJr-G1=?+0c0Myi#m3%-4G5i@5pLNxs5f8LHe2%aFl@D)sbp z5MrzB8N4gCi8V3b3s2@*<#SbI=7&>1MIO7+c%QzXC}fCMn(hInV|NEed-_V=_gcX= zF!$HJqiusbK#X*+7KL?Sr5A>wXsO(~&q(FtKQcQ&VOt7k+2*HEgCuNhK z2+w>Uw6&%`Q3|Ia{|U^xcaLk+Ma3|kXY9$?bUB-9%BJfnY^vGIMQE{M^yG<)Zpv&s zy|SobSJYoNF&GV^GLmunxK1=A18f;{IG2(u%!2zuQ}w07zy%M z!rsLj$Ca?Tbs#c`-=VMQ7vBrI$M=Hp==NHCFDRcT<-O&RXs{e~r@T`hiX98GFSZ8> zNYed@^0xnf(0t?RV~ZL-J}}K2bL{OA-$ zOJ9M0ty08+V=1_wX8#K(EOvwv(4WI2B>eTHuR<;iz+$hsafIT#n4|M`GYRR_1IZdw z73BnXs=7g*2}*C6iRVv$$IUg|qP^Dmk4OI>aX-cB3~P{*x>sadZc5k2BGxO#aJB^Y zQ>8ZiUc4F;7j{^zYa}e_J59p;hgE!Nf(nBn70TwKx$9(Sdl9F};2<}Zs24$s^Vqe& zg@AYwjbgesGrx9uWJS)M&Rr$#TiV$dP((Gn<&-IqqOPo*T{tF3)E&2AI*^?Zg(}GA2*Q z79XDbd>8wjbFtrf4(ofTdN z;%THxFX$pWp9?@jJj>4KEIeoLd=6!C7#OaXsHXt!Fm^t>*nnQ&#!t`;&|0qpiC59U z1h$z0n9^!Z9-7i30zrgU8?BX9DyY$lFqkoa@^svN_^!1wq(vBnX&%v93CBb5nN>MV z1qICBS~;Tg+YAb|Vg|*yOc?=E7?jZZ30tzYP?jXUFfarZO!2d`M3J4XARl*TXCG1= zNuWhU9MK!b0JB4iBv(q_Lx?01WS~g0gdv)47(Zb1qOl7Z*JF40xnt3L)8|1en7yE_ z#5-yuUM90!d+q7i-R+OzaX7oXRInbNdn{M5!KN1lK*~5d(VJGshO%iVO4E|@qiN%8 ztB7iyDizeQ9kJv16E>-2Lz8-uEnkbXq0prKs6d;_w-KES7!>j&Ht7`%iZuMONzuTv z=3gB}(NMn&A_G>_QkICMXJR5-eKX$dT~ZpqayyVJdsycJmR+F58I0)s9|ncm5(dSc z&oL;{ni!N2%k*kcdeuFEm_CyrGt;?e3fa18ioRa{*ytGwv7RRLd3Zi zpbjp94lY3>-iIuh)LiDG@?^6+EzVXIdAd&}}-jh|vqM^AkH?SW6xqMYvL-qXxFt}~%b z{L5f^H*kvDns|Ukwbo?{ROY^qNr4hO@J=ZZON6I`D6pF)x>H~g?YqLbMExo(vu@B= zJiwxGbc*}iTbz>hm0ur$QXl{tW^DKL=LF`7P%gpE1`5oSW-rd#?ceqtwcF2~_!9J( zD$I!ExRY3eUKD{AcpcD9)PBrOx%--p_J}%D*6=5ZUV^>3IeGE3u~Yafsn(=iPvewa z5AsD%(Qj`=Ttyw4O26Y4JR0p6=(k7tkV5Y}Ox?w0$vR7N^W1 zR2}1W3|^-#PJJ{Ov-eqemRyVVdRl^63ybkf{`Z5co$SDL!6eHh#l1QJ9r{{2az&*nC~%xzNveC2bQX(j%70UJF~u%gd8St+QN4Q-O9`1 zcRPQG9x^ZMBZ+;Pu~+x{f--9AF{X{l`a)tKWbAkJl?$o;1HZ=J{=!?49UY2C%I>Sf zb9~2t*y8J_nQpELboPFE3s$B@09c4T#J}L^86z3y-=;#vr64hkog?vq7gb0thj!xU zor>POv2|se{}oWP27qR0C#>9fX8unpu!@9S$O#GSe;>d zUkFt*RLb6ZXpEs!_V-Cv2B0SKHdf{(D@PV3D{-2rax}u~P_l9il+ou>`HbhW_&*Ns z=U>W>XFH)$+I06po$2=uHrMOCy^>$Ng3yWLQF z#uMG+q>KGe_c-Yf7UIAxRd0x%3o3s77S2brOluXGb7>J=%oP#VKcxl^Ab>{Dtmm!~ z&H8i*0~rYe_G8yl#_ryh7;vSiW$Hg8Ag0iikZ+kr<(f6^$n2 zW*9-k7}t5v9EBRL;>qh-^ehCaMg6`uoEYJp12`x%Q@Eeat58&EiK1MQNm24$w9C%yaNG%2UqbnvN-D( zoCW11k2Q#PY{Q$6-VC3BCoiRQAZrlkR4hXRP_G5eU>LOYr3%_B;rv^^;c3_V)j1$u z;*R9*wsUmBdBpNwr${qcP3(o$a=~g|G{o>5Gy|zDAIzF z#+8r?&-0cw-yFiUk(iXjooZOT`Q&l|sUO7_m@CfZ*`aySV=A@*Z1lK_?GlI`WaDBV zOlq7*f9BCOlB7TFVBqEie>Zs_ndVJ^I);~FhzBQbL&>nRJQ2^X;U%*miU$V|&+u~L+yf7X87kga#M%Ly zT-5I1hL?v6r4iCicf-rRs!mYA8>1oKI0Ee5Rd|l?XmSKtgSl8OiS{=Z8{c; z+6DJ0lNS3U=f0yvNkJm`6f$VmV`A?14%WLMjGgX_|Q-XoEV%2*f1+VUA9Nxvl^WlmtDWPSl#1hPl}GBVq*qr14hEj}L zRf1IIh1d|rW-xSA^N)O{2_Vgl#&+GS}lXE+f-7f=PI5N^laGag3sZx~{t# zBm}ut4n+Fbf`n%>z0_^_&?mo-&km;|wyQ;dny85c_ z{wqIDHa=$Y<0#{Ua*cE~KK{uM&A341VJLGXbtbsMSl2$0z*Pe4L;_WTD>mkd1P(AA zCla#IdfC8w+yMs)=ZS=vblFC_Uw=1WRJ5sU@d>x)8z6dkqn0dg9T@En z^WMvndsE;__%1^mQv#zs;a3rab6=saEu+S}ORjG{8{fG;hQ2~5OF~-^N|(^il8sm# z#$jL=65xpt<{v#2%OP2U;CTHfOm@PTGoA=FIgg;4GX)mM-VQLtcWF}SRi5xkc({1{OQ=?92u z^w_ZUVk{MC?g@;(F?l~u?7*inUh}h zbD$%)K}W)$Ar|1scSsC=7BJh!Ly6%%g#p0VRhsZWOh{RUBuink$4ubV2L!mAz{v%*@_a^wI_HWNuAqoOex%rUM0@Vkhg79DS}C-Juy?gYm3`ZpqMhg>#N&y7X$J_s?VeDdr|bl!;s?D*CQL4N}DneUxCqs!>6iz(Dhyn zZPWszhlG15ApF6*2=F9Q$U+d;Q){Kvnn^wV^@rg+rS=dW@B-MaJ+PGloX)84rcM1C zVGO!n7(U%qP>Z5#rR)Wf{@y>x8wy(49HdZ6Sk2JJERcw<38xx;_cn(+Q$7YNbe*MT z$YN=XRyrP^3G+%V{sVc#!;!>af0I_qp;$o;St{!fSm0@f!@UtywFbe~;e273?_(sX zAg$EHnZ%B1lL(rbq}$84xp;7TkwhUhZhMXKRk!Y#U4~kMpW=k;eSeS zcHn8sEc`USq$}lNU~TF&e4;DO9YF;{ayMAr46OKBjO%{Fw@GFk!n&RTaK{cWd^tV> zqw~WTNo39(G zI}MrBR9%NP&FEOrv&>v&Tr5@3G=gPuu|5^cM0&fp*zu0o@2jvGjBhz}_t3@25uAhR zMtNSx@(~@~!DVtN!1mSehy?Jx*UGvuC4Ef{XZ;RAUk7p4-vnQiWy)y}{`%y=<*#)s zHz&I60|HOwoe~4DeR%4SUdozz1Km^R4fJ59@_H*6dw9O32IsH%F1RZ-#P7g4t%5%W zZfac^9u76dm=s4S%%Sb!H{z%S<``8qoa=@B=1{gR;HU++PtzMm!-u%*7#wH06>W>X z2pO|c1d!B*nh1UmXrwN>TAT)a<}4@!eTU{@#8-Y!%4{r4yTYFXV3yMlkN!{bjpebF z(i*LFH;VsS>%j1I92&qLOuJM9zbDWY7@je2P^Jr~2(XExwPM6tMwA4GAAsGP^KgSy z+Pp#6BUcgrUx)u=OK^|ol=qn^D=_?qd4qnJ3c%Di0C=?|aIP;Oo%T%QqZs#YPI-|Z z?!dWs2hRNiQ&#djHE`}ke*Bpq>4DI5Cm|&xX=OJf++t7q!~AOf`q;bhYix9_xyat!niCk561XmiJ5kXyFKvS&zGw!+d8*2nGHBf{3E$RLyXru0KToO1xf zg_a*l_ApHTl@E!#FwTQySf|MibRp47Nquqy{YcC(ok_IP9Vk8a;|eaGysfoXdI}Um zd*}nCEhstXN?c)^0>Cuw!Jm+-z_tEok5cDZSY;QUd}FuR~(P ziT)UrJxmWqxHH2QaSqST=GN)ZB2VySQ~ph$X)-*|Oy@YD9wl$>$W@EXbYYh(=OSvTSQQPN^XnU75LB zX)b`cbWl}hM|>D%4r7P2G2=cXq5z11@2gQ6TrK-8G4AD7Cf~Yxp_u8^Y4&+c);qjsqR${H}IsgJWlvnt21VgCI?w+~e za<8NjD(qT0i=n!TF}L(dt>kCoghWH4b-x8h*v}_t zWI(a+233e_2b_nC(aHLCxA<<{4~aA-#Q#%9Si7t*Rre|sS2Y*gI#Q7hW#8fHfWL*l zLqa)S5eVk6{zEyPButD-yA{qs5S5bN)y3oPP|~})`1eEhQhKpS>v$Dawk{Ppd9 zqx|(*#W`|^yqJ^o7uG&n^h z)p=r$A*uG3R5+i4*bNDAeXNwzvk9j_3R)?bD3l~9t4g{%i6U209B5CeC@o|B>ryKz z5knYSX$3MC@Lr5*kfP*eTUB}4g6ou6PEv7{&5pULzBBxp?AqK|2^^$?x%42+^_@Q7 zL+g$(nI*m+J@HjZK^ouO*sP>9>-;^4WH+v-mcUn$cPeswO>>po(#WkOHkGlGVpojO z(ip(#l7`n{EXA(3avG8#kY4%R-z1Px8Bma{N-rRF!>xL0!Jwvc9FgP<19Nz4@rwDL zRrt0jtY*-F%Oa0sKRPZlN50m1jIso^ek3g&LlBJ9}Ae175=-SVabN`U1yf zTswNeA6%1K1#@mg6yAp}7)3n3%(sXvm`OsBKfZ;|8BYR)GW#O3Y@zS0&`39K+4t{G zosd5um`SX`%-fLE%zo%Q%&xt%I@s+cfPLMpVqR=BJweR1*KxT(aKD;}ni9`il40sJ@L!!qz+_*jVYEvXrg`~)+p zasK)Pw5Q=hy)c+LLb%DqXZj-H_9@|KC+|z48+<0%z#UY$7$wVh9`gCx%Mx9rqr&>i z+X}h-1apQ-<~?TSHY#&>-n~`&7mRzrxrIRGTpW#ns=7_fIy0+CJI>Sd3QS1uzYY1c zvYYUCo0hjUm~#V?%=2(m?3(A{z!^UrRO5%^Z2WNijUNuj@x#$M2)iL(e|bl{63S{HE9pE0{sfMuS&M6&=sA^ z)@r3(0y5O&k2`l)-bwG#1q@9@$X`HdK&^Ob0;Z<9tPuQKF6qX1cApuEr>?!GtHlm# z7DgF|<44b1x2MrxKz@O^0Wtf7SW}2OCDK=XwMY5d);&g?>8@+#*PVOE3>o5doZ-@U zaNWf72858C2B^o)&~}_$_Y6bGH5@rSGZ`B67|fW#nBh7MzB6l1$Fw3PU|Ff^Dj2@PdPBkTd@XvfgI3^kImPZ+zK zpmi`o%Pt{`o5h*^ECTjOQWSGrzL5Pau>lq3I0$NLWuG$o-z7X9!!* z&|HSTU?`oTWek-v-G>Z4fzUIH8LDQigz_0Xo3J|xdxxPV486ioK12Ut$i>jp41Lbf zpJu?h99gA7zLSeul%@Az^wWc$X-JDW9Ue)=};ss(6v%Yr$BK`HzPw2`;{Uv?Q3T);=b4lo~3lddNGEn-my=sr7_ z`5v|cLHQ#i{zWa|nlEvI>aP7n=+yiUM3{ozBBiCS@2D9W6xBwCL`wxGS}HKnQh|w< z3QV+AV4|f0qn0XsqNM^GYQaQH1twZ5c|}VFCR!>m(Ne&|7YmblK#==5wLmoTQHDe# z1tuCPFwsbXiAD-cG*V!qkpiPeDtw}m0uzmtbfS?0TVl}_jTD$@q@)v#1T1_bnWWSH z3P_KJA*4?`m6qZkq~ z_h3kjL05)E%n}kYA4Hglxg$d&=GF{}n9~>%G4EtWi z0zzE8o$v9Y##AWRf=vgkjl{kSSUU-gu|i`JtJ>r`z|bE7OASH@Ak+yVSOJ8dvS7Us z>M5`x$a}to9ssO^goXl!0CJQ7cBq635jsUeBN2<~E@H<5cCdtoAk&X#2q`Rih*jmd0WihiM1+n&x^PZgqK_6%D?tz~90j9ra47+DL<!&} zD4bjgQ8rvLd6OIxSg`@Op3_=R_UniWkD52P=*A4r0 ztzn<8MRS9F>InOkiEVi$Kz3iM>8VCY?eYjL7a~#(iQ1*~hXPcw6rc)GfGY1gz!bh3 zgj5bTJ=H*{T}nf!U3o%-+I5zMs9mb5P`kVWD*-H9LWKw^7`01j4YfDQ(`S|H-lirt}pop*APV z^?JN0l`_(lCQ?fUOQx18Hkn%f$C}cy=CrtpVdrDt#fwt)ClsY>ueq?&D#WppilrzO zY>X9RucU^U(V`SfBQri_|DQq*d)S#H_JqAsu7ubtsa}q~lClXUfT@X7AwmkqUP)17 zucQX59CoT$_DbCaAA2R0j>ArcnZ1&l-LY3v=AXTiik*m%(p2_Js+7GEV#&jrS_aB+ zRmP0vhudTM0pG?8RiTL%s?xjY0jMoh6-%Kim@U+~fT;p!Amr+J6bv$r`%p3XmT?!6 zx74WqMnnz=uah3et@uwKgfb-%|1_=#bE)Ui81WCX#Xslkro^wrnv42OBz^@OW5rVZ zsCF$I9Wmmr<3(+U=?(@JZp(`u4W zomP{yXq{H+qIFu8gF3B3)M+(Iqfix$YNY5!tI_CaHFA5ONk^5O^v8o-;SM-bA>#MP zi2o#8{DU_ByTq?d&wrEn)lj=7;(z0Di2sqD@O#9*FcuAFV)0!6@(QdY-vc1rVAHWr zoYl{BCo0v~CDe`Eah3d|{~q25N9-Q zSOvynPmfVGkD?hAci!Py1`nLQ)Kx+l2Og7F|Hg@iBf$>XtOfcBOhM;`U*cg zmzOOoKJ0Czb49XL`cH9QZka%WIphNSVs)}15ZO}k1RVet09ZF1c=9?nq`VGK!4(x- z0UFY8&OLY}_r7BR4cy1LJ#~={jhSAADoT*C5T5jv3)@Oz8v|=Y(uq+7RHp!cf zP@#l6A*AqiMMzO|S?SzXx^ydDhLH|#oJ&h5XvWjyWYh4V6v+ zJXYm*;N%8icTGA%_M_in%|@zJ9(M$L%PMi9N*sAlk;+d<>eQn7r3b7NYY%FD!K&|o zxA?79xi8Et0p_Bh`$7@~#Ysmy2)=6ObmQS5D~o?YAu~i~;cc!t+HB8K$ko4Y4^9Bj z;Fh~KdpRETswC8o@6m`68>nNy8$FE`uh`ydq3O|x>oZj{nEob`!7!*~Se%VbhU)O+ z8QIpgdTX4;tgF?vy5X#(%uQ^FRh}R4bHW0xs@rA;Rv(67jXob+`}&{o=L#b+Bb|wv z*-ZQ-6W=0~56Y(r>T;dl?v558~$;63$oI)1LG(_xbv^|ts! z7g@LXj0D|YVBdHyxKLshIivt1xeej0^E{;IubkB@_zBR|;=>H_m#r#35J8Fs4XB-e zL5k9@$f1xU1$x*Tqj-na^;?7cm|<-7YoKrbxo*^E(@Y%YU}Av5#BSylCerqj36{>m z#1|M*3ll{_sh3cW)a`~JpuPa{L+7g?u-VJCs)Ya%K~XSMO0`J;fKm+QP#k#FLz@~v zJ>VGNm}}w5p;QR9#I$&5uxh#f7?bZ1L8ZW;DB%nQRwmJJA)%zPJO~9g1e<|dFCxBZ zLMI3z`oYxI)~Bid(2Y(xXB;|-qvizV7q!99O8%)!k#Hm;{i41Y?OTQT9+XmGov$H@ zD(id?3T8Iv>lgZ`@-iA+H&p{GRYpIxI-b*T``UZc2*eEz0|>OfBnjm>D^qggW_IQ- z3T7L*YfIL$JPh1vzK(`oW%9}mrL1+@`<`itG`TXM zaElM+6ylP8*nk{dSrX0&W#8{_X!ISx+p*{ok2auB!$F0}Hio7!q{qB6JzuNZR_<=4 zzXECjymJrxQR8)m6@Vf8T7KU105n?F(hBx(`rnb*g4LvX1bCGJ z%76+o;6OsOD>$cu@kPOD z9GXBi7~`Ll3LTSBO=>0MBlFBm#Vm?nB^ES=YFN@JBbUfu%4+UCAJVzf_1gK4-MtGF(?SG)?Qh(b3@9aG!MNJJLXKpUvb3@N-)%I46d9zs;+G9y|^n2 zV@dsQc&sk+6CK{%yk^5+uoO95lMaTv68*`R;~46xlCSs(XMJvbMzn40vj_)Ao7fU3c~vGpP?i#pmsxx!=p{FEP&0Xu4&E8xJUQ8ZD$6HvuQ`J~mhw0J^rn>I=ncAM5g z1rk%@*1SF+U06#fS+a0T@q@K#Ls9+Iol#16gcv2$1Tmg7Z<3g*lF1tyQP+mnBv8{d z%<}NsAuHwsY91=J_76uE_n5rMRcPf?+9C~xFAiE{i?rhxjNgEyP(*`7WJPifV*7CF zsVUjZ>{5%uCoVO|c=}i;`Msw!vPG1nG8@eP(J<`x%|BYz8h-%|y36O`timg1rdo2% zMXul)Sg6Oavf;cINTm@GK7%xoHDDfxlz46%m*%D8)O=M#`K9RLmg^6pK?dj5ew!6+ zz&LL*zR>%$*&5&f#N^*rehCeXj+ZGKgY$8}|0?})1{-2>njLKyuz=o#1BQyN=!EqH z6)6@tro&aeUCuBhRilmafvH86{H)-#PUi`4!#MVgYhR&Ev5t%V8(aJ9Xad|{P`Aqm zq(m!T&!w;m%b@$XH*)nv?;$+$c1TgCE29W&6kWd<3@F}D_zKd(?;%*8kQ>vBv|HBU z|E41Cns17^2%zE!&gO#FgG+1~={wNFbC+!#sICRT?8e zegy0M8!=>=yih5%fH!H`~Wm8B&N z8ECimYuIC;9eCWg{S{jE_Md7p5APG&#=D*#W}xjjctrxVr|uKlPR9-&VW8c8SewFl zZZ~2UVcEZ=^=Z|LA%s2m9dn(5_N<(p3AlY=pU~c3c~=_)?FEmvO~7rReL@?h30tGN z6$|zyoFAJO0-He(rU~UxtGjZ<%avj zbc-8~%fqYFktt zQ=X#v9+GNI!>p6UdNgilQz8*WJwv{*Ku%Gl;U5;4tq=_YP0T#c42Bd-+#uDbG)GjL zw%o<(>}ka&ozq-i@JWVyOu~Yz64T^~-mLYY>+7U=kY<(Y#G@8!MW&IpocZCx%PfZi z;C}X?oIh7Oz*$bb`DlIuSe~73%?XqON6(L1FaaFW433lqur!GW)-nrh_oG$cn1d&r zY?NlZ#6T-)Jh*kqAn#HZ@WoY{?Rd718a5=y9l_Utuk z5-C$gN=*h8#t2_^3-cz6{fQY}OEd3clS`r(c3oLjWDHy!RU}EndZno$(ddH99*UEG&_ZkMJG&G#O8d#&cs@hxw-hpgiWyzP2kRXw3xob$}_m? zpt@kQljT_{qsNV$v2z}qBbJ_;YL+9LL6btOsLc{dm8{<#kia~DqM8v)G#TEQhQ@Ji zuL)I1z9MyX@#uubx7OUcnTvI5iOn*%6k_D`=55i4Ci2IYRTh%w$?z>LMir&N)8G|p zo2V9)xBML2L~*(*3rAA_)J(%jwM5=xv^unue3Yg+nxMl#8cndpv}eGHu|-8EZHuI{ z{4{3!QgktH2ey>FscD9^v4TNG*`|#&4V`6uT3qxe!_J~RMwa?0m?mRnrC?^$leA8wcvHiI%B3)&1sPSFp?OPW)ZG_|Cii)^c2Fv zc(rHwqY%oB{8}S5yNRIkAy7M6=O6+rzWN4YGluY7Rn8d+1ZvTi7a$y4@ikViu@yNe zqgAVPk(Cv6;fZWkKh-FiWBVBUx3Z?J z&qoHVT(fLxvLCIVrKm+Vn@i9KA*-xC8wrj;0;Wgtx!-GVKEEHe`K-Pu8CjS%_mF)V zdM>Q0K~omLQMSl7liKN^MkkeSPLi)<>DrQj&~`3~r`d(xh%L{d{)Tklfia8Y<{q_^ z=WJ|w+dLa7EEqYDY$ETW%y9^pU&w`jyOIvZB+Da9@;R~Gsg?S1X!}N8Y+|7bxB-lH z0R7O_N`TT<)UIzRM>cOaq=}v!wN#Wz?*fmJ$Wm&N{tkp5p#PMynW#5HhxEUyx^irQ zi$? zhsqg(|HzqLu@3qC>-zfZd-^UyTDet1u_3MVPO#D4=gsCrb1BPyklpF`$YnSHLMoxy zr3;XdG(l2m5*WE3W9AHO#9X_UZai9`Z}qni5_$ZS#z_d^^$vgy2r-zY&? z2wsIM!HJ1(DU?A`CEZ>S%Fq`=8knWiEvP$QC3W!pGfb6MRY0E^)IlTTc8)8W8UID}jHHBhBuwR6|lAG1NLhk%$6_ zf__H88U>IwsCfja(pK{nfc_={)hdOU@8<}3zNCOnW{IzZBk%o;DOUiI<6QuR?`kw_ zooc0D2bg~Mr%|vA0W&O|sm#J%Kjx=qD4deN2Vjx43Ls_520%YL8lj6BUC0=NRf@O~ zol|%tRLOzlW56P76QzEWso%6x3l9~N+L3)40Q%oPiK8c_xPut(h{iD5fk9B7PYh#$ z!GZNuzzmkO(i5W*9D=y;A%M{Yn;W~KZtI|4WowJu%TtWjgD$~&4y<2)Ax(w%jp-d$ zNLz(F^XJIuDn1T*&r@lIt7@dh?E-KS<|l4MU@H7mH#$8T+*W-S>(qyheEoUg5}WPU z(G}F_FX21#I+iR+X-H8ee-tiaa4<9+L_*z&8k*i#Y-Bheb>~RZ3rWH~0do{qt6KFo z&1Cf;vcSttbT3G%T%x)SpR=TWO4vQQu@_sTcS3^TR_CTR5bAI3V!9grX%ax!4H(QM zTdF<)HNvP;E2^u0K9UCpdo_ogrjZgJrqcYp!&I^>pD^_2S19a6EFO>2pF7GCTp87K zodHz(43M*WbO)WDh%DQI`;u^*f8SNb8P1aEXCPDLdlu*t$&Oo^*gf%D=d_abtpk~l zKoGT?T9s@_3*^vI&D;7}4pI2bO6kj1ok+#chCP+et;c*s@T#lQX$TmD8eBsD&J1YLl`+ocfHhm?jTghFp~#A1Ep{$j{fF zkD{?tvvA1asj)cZu=igSAtscFj;St|r*?#>km)sV~mSEFp415xanYev9xlH`l%zoqPOTyQ@); zKSPBuZZhl9+8XOxXNy!-tJC?~^A{WEheHxtTc&?`$y&zJ&phu0>p_Ii~B zV`kk6rouw@c8l!aZL;l?lC=wGQ{~KCmgXGG%w(iy1*Oey8 z$ZNJx8!%RgU$}9seVL`(ho!I082d;WBmeMk9%{7xU;=_eadd#@lYW<+Z^?&ASV{|f zfUQ&2I?x`6dUNr2u(u~BYQ0YWdr>`pd*6ES=KlEY+gE+(8{g?P2<1oz3+KjfZV+DW zC%!V6>XVD~W_({Gz9-`kka*t}aG>jn|G9r!yWz{#Utr>exnI{Ft~1!S$T82F@Yk-A z#CsMp4fq^Aw8$ge20dxDs}OTut^*m8xwSrFRVbeqE()3w*_$=N8%&zcO7|qBWTID< z4|jVso1jp)EFjhdri;l{!xWilwz4Q-wJynUq7(+p7*4#w;lzuF8^Z~~6ZzUPrr;<8 zH6d@QTYc|qs6r)TV_c#3Vy&IK%Ze{eXb7xvMGmwF9+K#L;V;=CTa77BZhlO03i63R zq_M@v9e^gr6AeqPR_z>5nEf6-KI6((i?V?Vifk3<+TyF58d`KWn?!WS=p0rIY;IU_ zPO~_atxImM+uLRBYA@fLMdd?dF-5g3S=Tzdxu}xwl^vV$v1wM`u>1DOP0}+u!dS;K zkcHT(-Nqt*vf;$x7D=qEn?*E+6HZNSvWR;zoOtb{1V!XcyR1V%QqJXs#UoNdIfJS8a zD%I+3ai*pCa#O)+)?`M}m0OSEI3qRAro6*bNvg%CH=*n@o;=Lt0*hvKA$Qq298zIF zvHYDuuE-3`l0e_3&*j$}YT&ZcA;%fpEX%Hy1(A}AfZ|wXFngJkSqx3;lC#>sIabFn zaoQjUuSbx($4p*3@#}TP>!-G4`(fk(CF_K@L2T)k#!2@QlVMT2PRZGAR_l7<|-Z_Z@!O z!p&D|>)4Ak`q*f1eyAlp<>1AC9KHCDGrjopFaXJd_kJF{`1yMr#voZ(RL;hbfUV8+ zK&$*5trCyEpjGD5uixMd;~fq~3iZ3v2Dm{UWR4^05MCG)+etP05o-v)RGi#&WU+S6kX#kS9~8MtSPd%$nh40eQJ^ zp~XuconMRv3I{WxZuFppGl26n1yOtT2j3jz`l72i&Nk7uc)gl_uuTWmpR~~MaKzXN z#W0=rSg&dbYZS?0h`johE>#z1xv%o{!~%ojrF@_|@PS%E-JqjVBM@<(qGOQq;oZ>M z77>gQj`XYG6kpG{OC9@<*hdXVzzuvmjq#n-Cd z5L2s4lG?16itad@CDb+N+1c^UShOnmC0v;O^TfaC=OIutrC0A)pjx{M08f660UYiD z@_Q~Fb0q70A?r|8RWwIjp5nOlmr5N7V z{*V>?v3z)HuwJjlXH0P&6Ql!!wa&u4Acc_y*Cm`G1+a-7`N1lhX-icXcDYjhBJJK9 zIYu2nfwv86;`yj-mJOY2C{bid3kVfjGLg(0GDl0*DH9w)4o&oC)AL*Z5OOFV?hfw4 z#&Xj#>4G5@_0cJqN?R~rQ!uw?ClpL5TMl7`lw|bhk!$azB079>U2>_!P_Y;BCFd`5 zqC|oNCa@Y`Z}o4^H4F#4AZzyM_T>Q`N4;R0V_B*1%Hdg=BCRLJ?;|jF zKW_E-lQ4c;jLFdABJJX(McO5R_T05in^WHkf%!m?!;Toq=O7W+xG>yr`C-FwcT|R~ zdq|@UXR}7@(~A4VqX25~nC#S|Jjvrgv>5VgLFtZ9P&%BLoU^nQGaDsafs!rS+mb;# zSWXxz(gCg>hL~lcA*-7qW(acx1bf_i5%UtzSpqSyftUdmF*i`mpCx7{P8JY-Xp}bt zqr9!gNbe_%^l*&EJi!TEsG?Cwhxjo5Z^vlx2c#KirvWX@){sia;j6GVm9uArKE!*y z(3s#n|F?KCavZ1B3xaFH*CIgfn$e;-IYY*^P8oCH4W+weujL$Gn2S%pAzwyhhA zpx-vz(7Eut$byj%cC5Ri8_UJPVQ+Apw`ZD12853D9d6%MZof7Z^y9)QyD{g}ujtoZND75`84yBmT zPj5ft;vkizBk9v@h+D3*ud7_UmkGJkeghruR^5Y@I#xmz$xF|uuFy@ zFqm+ZrH$UrDn*Sxjr?!3d)}TnLWZN!p_~BFPToKVh&D?L_@k8`A@+SP>Y4Vv7%;K# zIwPxOyTi%ASvy#na*)WVP(zcCLxkS`qfBI45UtADD$7sYA6GiwO6kDvp9NRF9g(gg zHmC^Qj%ceQ7OIHNc7$?Q)Mp|h+y^Wd@DdKK?C8YY2UUJqR*!0Kw;@6w_Mww|gO^JX zW3UbHKq-W@#EVp^9L#4a9{VA}$dDb%lrl($!&C+b@10bJbVNiZCXn^opOVOW4kGkt zmpHjK%*G2UOT4TfQW5bY9gm0|9x4dzauu|ox-b4ncdAdpmWg8^mVm{+3T?bV4@HFD zxY)^}AyALX;$YFJ!_8QE0|^I<*-AhwRKzCKdhPlQL$-$Sc+ORP7sPWWJXl#2V=Zqt z?6ZS^YkjpMVSAw3Pk9i9Kb8%HUsLzsE6RDn4-3=WnNEX2-uBvw-~Quts(>-T}s z6*;{~yYyJ&U^Jp5VRTQjfHZ0@Hd{P>&4DLeUKasAYIXuNMYt{G@Fw8(-I|@7P z7cawb1JIs2#v)-3vp!@NW6Z~4?m8p{n!L{wFyIpgdVBR>zTa;Kwt|5l$-qa689>QU z+EExDW*I`0?Hqw}Obkh6c=bDMM&MM6v@+xbRt(G&3^_0_`YgdrGUFxqIXZB#3E zp?^1~aK$GkAE?SC#+cZN?~hQ5yrh=nzvW_+7cIVa9qfbhEkmQ{!`-~q<&d|QmY5;it&9B-r$#H;k^%Ut?iY7{s~u=vWMA2!^ft*)L)hMJOE!Tzaac zlPmjre1?m!$;rXkPCr=xik&aLoqIIGl&c#LRmPsoxDZ|dNOy={#dIYY+sM^4L9{D< zXr@c09L$tYBPB*@-~8Pqd=#NUmA|V#0r~xNy;$y2{`7d>9aqfJh1_k7u>woI=pSbx z7d*2IK?zdhdK{Br*_nlTAH4>g3NySbzCFLB;S;U&bO3Cp`o3Bz*2-e6k?A`st4RmF zZZ0m#oIf3(pd!~G;x4&)MU@PmMxLhB1C#Pv{zNOIi@T~7SUZ=#^tHyu_s9$V7+t|t z;eq%7k3<^26dhzJ+lzI6x4!BhvLTa>b-jGd7~H`{J8=Ue?k=6TbM0YuoEqS;sb}YE zt!mj}OIc7wM3&TU1`)O)(t$_1c(G@Du{7leQXtIR`BhO+!0;(gcj1jpC_QjwC>*lA zeBq zH*R{ZTAqT1%N-D^J{5XRL6&!IqgAcNa9Z91MLSEugkUXF1Q+PnB2DlEMP91;Fpw|% z-dAeSJ_<>B(!d>Zdx!L^*Gex!jj3Z66A-eZ9i{wgCdjJPWy6uiQMS2=3ik)hW||d2 zmY`BQg4=hl0B43K`7#~a>g#WwB!MQsfnu{@flSU)0@47?_JG>~*buPx%Vr^lA$+?f zVNsUT$skIaYk4(Gm)uV&$Y}>2BmS9po`Zb?Mt*K}(&8j@;L( z{3=|&xK^oG=>;ewm3k+yhNSqy1%S|v+5If}3Unjqin|rm7@`j^L`W@g<6%A?*}*?t z1&?N?LiJWC-fbLD{#mhdBOyrHnOYW|)A3BIyWU28l z9Kt6B(-_{s2)CDZQJ;FIDNiQC+mR3&6wVc%qmm=zCkW}gpTnPPU~=@ym5q(l^vDtf zhajlmKapgHpz7I3%#9DNntf;GR`3=+2t;LNBeF%mx%OZe-ct`}0j9qWeC6znT;X(l zbD=^%;8|%}{me_;tsCF-lHd5=O@I1HTpW+*pBsyh^mE}t+J(LnV~xlbJeO(Qr>;&$ z))2bdJ~-h#Op&PO&Gw<}k(m76FR@Rn(~F7fL8G&EEMYsBqScD+UM^)7{Hs>7evh-L z=5)zi$+`-#xRtCv-&o@^U#5u9?1+*N(v(DGkaRfuOEG#u6~)kF73h9y7HMRHAuM~m%s*BpYY>Rt8v2~+OeEY!3m59Lr|p2 zwFLQBxPn*$M3P(XG9-x?OFgUGT%;>fjH^2Ne%~T)RmtAY$LG@N~?I?WNHd z^`K7sTKVUt_&;;iZa9>+Si3&E%_5A=+B5{Q5rbj1+iUKl6hz7GeR49J+I`eVoxj4$ zYC2X{Gr~7R(@Baoj9<*YSnh{Jd;H9&!aO^qAzP|j+$&^5J5|Hjsu~6^Y>(Q2 z=g3;!0~PA?0Kz_hN~#9;4%rvG2Iu?L)O+~Rv6r`|mN9yw3?5$Omb1K63Ih|VM?vl^f!MbXwqfvsX} z2j8;I+Ai*dE#*#MbXBsMHDwHB0}m$oRh>@`JD*k<(h8FD>wc1{eGBBW4}DKev62-C zo!C+=HvS)M$y?O{nXSYBO^}q_C)w}d9w#hoT?wFB^WkCtwno-MIfp+&3$xg%-N%0DQfXf^ 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

Kmwjo-7!P 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 z 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%0DDBYN`%oEN8*Xcs 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 z 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 z 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%0DfB}HZ|_AObZr; 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 |i;Ba5xeKADtZM+u2vR3sKVW1vC03DhxT- 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

-5n@47KBN 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

    D%SII^HX^o3)^0}X!YSdQx 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

    5F8(8ZK97d{Gur-pz9btXrD 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

    fLuFG%Z5pM@ zefX~|qtl>6naLi%bYD9rYO~!h;=D5U*f{GDU0i~>PjMYsHqK%dqIBQfP&U%MJ^&g= z&{wYnLGuXuXAY>O9iZ28Kw}76lmmK{pvQ7R9}{$M4roB=!BBQ;4k$s;%{ib&1pOih z)JD*-9MHf5fKJT;O(v);2lP5Y-5ro>F-O919S4o9gawkld?cpborzYoHv`S{cyaFl zY$7#2dWjTRW~uzGv;FAz&i128ya3+YezZKe{b;$f{ph^N&J~5u)$X&NK!)#JfmM_S znuq!Vcw2N9O|}=A852?a^xdaUJf%IJnN#>+2srk zF__p-Rr?I^(Ps9;a0gYr93Jp5LoA$3H^nu=(AfrHUytyW7%_V%9DXBvf${=v#{GyYvzP^% z?3yPkb|>Gi*uC=`#ZIr5Z}gg!d?P3S0qn6kty5~GE?tb9Y$4PwL5wq;` z-$}UA4-)b%(Ure=!W8irojgsxv1h>-;oYGLv<=mu2F`sJyzw20I5Kz0POr|QIq_Br zUiw(2d`oWot$d3MlkzP(Mwf4_=1%$MMuQ}r#%S>U1j)+WF$pQ_G&RGnli;Oasc*@S zUx~l?w(;^U8t!QA80F84=FMkRG*guJ%8(QO!OjDP6hFw!CYz&gK}Aun~?m>ui77Qw~VW zQb)6X1T*l_o zI$DJ*NDN!X_RTt&9NDZ{5xUrjTYF$qFJlXDZKsP(wzZWmwwu-mbg?zI*3iX<(^?4^ za;O$*%5HlDIgWONPY$dAym4c(A$8emAQh^5GEmju=>1*0RfMQ<8wV7LLsG~J8COCaH zmj?I*T#LQ}dB;DaHG4S@He#ydFj$vYGI#4+=WkC$u?moq(_%y9w88@mP?LsCV)IiA zCuq5J5s#I_;^IE&iC19^R-FOIa?CJ1i7zE&vrVOhLI;NY?s(SIEan>#ie`(Iq!`$Y zHBh3E*iM9#%|vf}t?nQ!k5!Hph9DM(m>%;Pp6fGY<1C3oppe~134xXWJRuJD!$1h6 z=O&~bbIH{_UErv~T?v8LS*@Fl)w)UgV$ojWQeT3}&pF5izzE`oeYB_TwcT&$*Dv5`mTYzRccE(Cofoz>;l3B1ZVi6X8;DC=cZ z57BakqveK!LJq#|3E<}f&wYmj(BTfn+~i13kB@MyS#-+sZ3@q#vRwYj@MzPSG-4oX}Sc zz!t>xhIp@Z4Vz)izm`G3|5aadQ!i*`OF?Bf2*8%k{?mVh>xaic>rbZV9dhFY z<7iX!G)`j`X!Z9pCo#Um;mXgUFplr`P;vWkUGo8`EaO}BVW5Ca3&o+g_0*=%h97-b zsrk4J!qr&oon9|~3pihT=!qfW;86PRQ%51F`P`$7YKIz#RbXI6hR&!MBRmfDhTp%d z-I&E;6;658nKG)Y&=#8B9LB7O!=#v89T6g1Fo5Whh}kg(r?oYjCIzY!PaT4*E#tQTQ#a9FW{nkvI$S&CDXc?b)@T zA^1U~+r zXt|2rS>K+?r7|mAc^EYDb6mEIUjHEIRT|8)L=1|Nr5GJMdN4rtJVBl#srzB~jS?=<YLm+7{Q;Rbp`$i?K>op*hTc|K-mpY6C$i-t>b$wJTagxOtTfq{GwpIF^4X#er}Yl zO?qs+=LOorHRBD3zVar0k<`A*%f`1PRa@pRA)?^ax&^0H*>kX$j7BLq*xk_Hp1p}( zOrIc*B}K|;_GiS!vag}~*$-tL85rfdjYl`_Yrj4=OUcaa;%^lcyhJbM@doX>Y_@z zZMVBfRFE@g&!39lQlHJarOGQ%zi{eP;#yV}Nl4-yBVMKUtl{83F?)k)?yj*_6v+nr_ zv~R}B?AKTWvA(g|0~?>@dr1eD+5K(4N~BaHt$P7XtfkBWfcu;4MElf(EC{OK}q(o zV}J#l4etn>GE>4h_xwN>o>6icohU*G0Tq~o>!H}(BW&>29OHCY$(=Mp&TH9~Oq(&h zL9D-Y$k)Q_k@HGpA?LO9iu^f6eyS1@X}u*stpr(jk&%ZDq*bstD>mEKyJ;mfFRem) z4oFcf=?ja1VQ+Pe{+_VaL3-H>q`)E4_ zb94E4Ltxh5h_8Q$cu%sm;|&2I8cikc2PmsOx$+`#>ox=e1dD+#WSokIW?08)2(v0A zni{&jXj+p?)sUe_Z^cT`)}bKn&GSR!4F%w-4kV$x6W)Z$%{@>q-9GQ$N?w6l%V9!+ z18u>M(h+9;nfUq|u@$|d=yDK>Bq-D>Yi|yjC7y1}jr(ZrS-42NOU)5@4^D z1oUtdAVGc>h+P0@kq6s~v{;cA-w}5Fv{%u7zy1ZJKHLX$6Pm@t)}A&v;BdmQH?}^b zf7yK%aCgjC!mL+?zJ_kUWT03H@<|n#3sD^d|9{NA3wTw<)dqY{&IvgQksUB%geU=G z1qF?KRzVX9f`E#CsCcV<*0xG*wO=is04mBp>?EA+=3tOZ(JG47)>{?D1_TYcXu`!- zE?xjz4dCT$winb2At?FZcg^1C5`wm$|NlIHo+oF|teIIevu4ejnKd(O2(x1mEC=;tHJtyC*fYK7i1;)t>8nLeGp2M*_|7ip zbu)n!M?n)LfZBr>l)}8A)CU)o!Z%XSAtaT84=IjUKHc?w-L!}-F=ruHA+obs(z8zG z<`?k{R=iH3+#BD7eM#Jf_}cF*Hogux^Shdm$Et-0IKdM4tMVT2P0bUN^^_Xm1l(2} z!ol7{d~utsUph_GCo|7@=cyM?6><8-d9cdRY>(f!o#fG~?g6RYrqwD}ibqWy3cP~g zK(@Ou&?^6g2x`!m88J2Mx9|66!!4X7$Hw_donH{TjWc+eN5~95Hcn>m;}O&V_Cf%s zV@6AWXodmmoGtZ3UtR^DR{IW-eGz|}xOOz`fkt5qaeNWS>RV9kh>Z)tdk?&w=WQOQ z|4qg8v%@g`cRHqWc%2v345knzEJD*4vC*K{5Z@{(m0lTr05VO5zMVS zacukaV@9-1>zTr_YLe@5?Ld#vebD2Y-x01&rFjIX^|}DM0PZN$>NnU}s~jbcK=>@M zvR1i{?SgX`V2v}_3Z&?wRbbG9R477A*f@701oSFIrIfV{RM6|m9tQHXM1GFz;LWNT zQ?MV8wFH5T?=IlnrVk*5&@LOF3U(E!7yxB;8Q^t<$g3_aF>{xSxH$j$BKB?F`nkEW zip>CfSxG9F&t!7{WFkBY`cwvO=S46M-pN328?$t4F{xowAZ-#fN9*k~SxSFg-UR z?Wd1>wNB*5621+vO)J!0i92t}pOANt%JinnIUkE*tRN96xLFUF?M@(CeG-Sfs#Tc+} zVakxX1e2XK0mR!aM;tPb!H}6QfT$7mD3B(A&Ie))o2dfGAlG^Vs7+WH0_Y)e1i~XA zfM9<~HU&6PfnagMspV>8 zOyFNac`gG?3zdQB;pY<^p%hRRegwzE-XM!Ps*+GsMo%HE?>9EE&u9p2$-S z4WDVaxoR|z4^*xs3bR>X>kc>^*w~jjRFfDZRl^-Vb_hXLkAZ6c7oVeL6ph&|v9Ut= ziwTukfdnb}IaY`~3_+X~AV6jX%>ff=3ITO$68Uq_;CayEPS8*Zm_&x_U=2ip)HFn8 z_yVDlVao8JGW8|l z0yor19|Rvld6k;w3bl5vK&*Hp?2RnRmBovMN!cZ1|H&f4nf3_4mx6GcXr za{rF-gP4N>+f+A6Pz6n85cjkZbd?+QIlL&(Z47!%xvA=~UsBOZBw84^kE%xi%+ts! zlK8Uh`;<>q7}aol8Ve>khY7Om->N9$3)nwXKG93?As56eQ;5eYpJ)@#QSOl{WT^7# z@Y(&9J3==v37{%-UnR|?jI)_wq&j6yh z=S3xyOMLz8=ai2-JN6%yo9l70W`J0-2W*Ogp#0F^Z61z#%K- zpTNPZ^A5VBEMuJU-b%K=Hvmp{rvTw=-8hhxy`acG0b`43KR>79JP*_J0oX}W{0V(G zx@elJ7%4u%e|&kzlp1FjT<_t3$8x0~-vamFyA~>Eq%17zH*#EuFn3oHD3FrZ;TdVm z;C3v7+tQc8i5ZQzyA$T_P6ZIAFM}s?7`ukc;K>}nE`$(}^}-9-?e0?QxZ(F9+>G#dN;&hy58&TpM3QQzm;hf{V2Q7zFNBqn7?slt_c3(%^RX^B>O zCK%6c89cVBI8u#cT4e)TA3AX4I!PJ{v$2g>Kxnmbdfln*O9G)nJ^M8UmZ9cR51i+L zMfCHT3{k%qWXBQ)d2jmn@!qezu9U`m2iA4wJ+K|7j>oZK z4`S1MrZ}*E%KxP%8h?vL>RQ?ZP=HzaK2A)ox4Sf;j?- zH+&e%{$~mo+^Qnd{-i^&yH>hJz-Z5c>?V7sTP&BK{uf)b#O-#7pNdzSzKJj@BQSc8 z_rQ5Dj|H&1=sev6194)WsUw4B#qK=w*)QJdaDJD9>Ch92{M>cYCjv>$Qsz}}d0;n7 z5~9I_CG!jCC-ORvd1bC)4>GrP)$2PCzn#18Wi8USKlX&_^)3f!m5-rLiEg_To}^Iy z8Q2k`SQ#Ki84KDHjU@}Jkocu~EL56wWgD?x)GWCTENLzmze?k5@M6^gsK?a#U-$5cgAH@F@h+lyhm88E8p=y3nyI1Gd)1RE6a@61aRm9lm6I>`QKQ`4`6ry5yZ@gItdO$7kTOcfn<7beeg@%wBB>)#TC}=O%ih#9NrBo=g~JZc_^uShwBnH=3|uSt>KjNnj52y>bvF!8q=T4o@xZ zN0_rqXi|uk1@hX8CuW4mAFQ7j5ddtFFJ}B#WNp*Ab1w>d==+lKLT4W%b93* z(eS0u!BLT`*D};^{~8H!`47Lq;)_Zs7rs62LX+*lU1O%hUE_Xe2(5Nuw=?L)jsuRL z(WxKMrgvW^7e54vejpFGgY^UXVn0T!;u;olwCV-o$WupO^#eV%%7+Eg3-8PE+@Zc( z8@}|fz!*+N7Zs3eac|+dlH)EaNX8>(Lu(KgM=Q@=2=_RnL!0%mUN;7A-;Av&sT+A@ zGIDW!BD(X&TExTCe(KYBHjaX5m2vc5*1gwEtVG|1N3WYgd|H$m03bRaKC7~NFQ{c! z$MLJuL46_Vc0jRcLyZ8dk4IzEAtayBRyQXxX{onw4j(=3RK0yK=95q}wSS>i zadLy&#Df1M<#orXp*4vkBRmv7cr})@^FJ=6Hk+{2$)erUx zpVVBf&a=x_@E^1}G)b!05!OpvSk1cGuK}c@^>W^cK6vi&T%M5XaQCE})&Zj1>f>3_ z>Nb+`ShZHUcUljtdJ{0H)^cb}_OLc&ix=Gisk;sPUp&_~93?~psWZ0Lw3}d+G(34# zIq;g*6A@-sPr$DwZrCLa%MB(#d1n9_kY$R4;WEA5nl>E%U(ye|2^4RE>LL_(s1L}@ z>dA<2@4-B3RS|GIkG2S2<@VBzJW@J7K$y(zWK~~lT7P{vvU(Sam##9q3yG9@+9O1m z%voJLzW%Q=!#GEO>|C;vrm+8k_LkkTB3gY2Wk%Gc5>=}lz?4{xY{phXZ{t@N9o&hM^WbO>~rj5x!`xq3Cq*|W<5O7B^&Uo?6xZ+dscpbFQ$JV#`%9Ha_#xg;i;%b zbKyK1xY6s#w$Of7F~^z3{W2=}k;pLTL- zC@J@{(32U4s|<6fK`G6e4vPU4akqw&BJOYc&b`qM(d}rH(1z$jN#VRMy8x?vIHn&z zxPuJ#4G`f>GB2oe65xwgQ@0E{NjYJtg-VjrZd%oEuzDK?(U0R;TIKcd*xMu`b`@3y ziSKFPbDoVZU5N@he}aSvM5}`+p7Q{($&r58egPPAhe}(xLeXlzwF_5Xw0b|ViE&_+ zl2M#@Ia%yivh9gnt&+#-&}rWK8*)A$ZX8M{RnLZVU-f>}qM)KsulpJfUj=rj<;-iv z2~sEfBt%lK;}fo<=|U#3j}MoK`jQ>{8gJDqd%#cDIjaJlinGum*`+1goLkg<6lAUe zncX_cRfF(EH0A;1jAOyk#VmPCbv;qzPtKo&aq^b{!qlOLEMp!48O0&ob`~cLsf2Avz%mHyLs)GB){U@kggu&o1ql0c z8({Miuq?vfBkYa@EJWA_!loo(*@V>+c3A?JL)fE)otuDlCu|;JCnsRJgxx_{?*!~9 z!ln?Gk%09e>@vbWlcf>ss}XiCVLKAAJi<;UtT_SeNmy^fUP!=t5tc#N(gZA@FsuMN zY;MpiIv+#W4#K7-V7&?B#<%_R1ngMCULfp}1gwCtrG%ZGfb}8l9>RW zuyVq9FwZ`;&nrtIVV4lLCjmR2u(Jt!I{_;q>_>z(CSd&u>qXeJfI+TBmp;Q@^N7T# zrW^dY=QvERAcabg7a>#;Dm^hAEIp~>sKj7&E8>@Sn+`w~JD3*zDFInwjGyZ;f9w$k zH2R=?hHup>PetgE9;F#tbunBiBM-Y(>+jI5ashXd-M$9B=T7N8pXBr?82YL=)9W+eO&X0)T-P!IU8TfAevZh)H81gv>74Ow>xOt_eHNuC$WDAuf{G}l1ur6UcfDt-%7 zOEBKe`PECKO$mcd%U);>u~S~zO-(hN2a^zv^)!2)jDAcqkTV!;Ec{x=4G#w=5ddBR zU~>E)MO!6ONMx9TfwLb(9+ZZGECV11CQy&#FMOFvUn!P`k7M%&bAcqE%?F!*$8B}c}S5g$T6JcLz&3zPw+n80WfC?kqSAkCh;F=a?; z$IS%$x+GA>ln)8KAPJN~WfOsCB!M!jtRb*p5-7vUp9tieVs1tfd*p8JGQ1qZiBbFK zNuZ1`Hh~u>fil3nN#O7#P)3-w1P)9BWr%r-z#d7Uj4_J{Jb;-jAW!amcTocKpAQ>2%M4x%2@L$ZWY*< z0*FZ~4#L$_-f^yKmjULjzCTV0fOH#xATYcPOufaum~O2Ww(u&u$Jx#%Eb4` z5kTcmeQTEefbvp_gN`>>`M9#Rb-0z}dPJ+b4IaD%a0@=3e42Cux{1ExJUVZo(|D;8WPvI8mWVhM@`FH*5e|`Ns?jBKAL&zs zmjiwlM&`UNoiy`0e=nl@w-~#E*|2#V2wy$xG%O#d<6Q5kaiw`$^;~37TA)=$@wKiA zufFn%E3PoN?cdXIu;1Vv=A~h0s?nBNF@{!DeWxVt!qTX7p7?u4Xb#qSuB#ZK)EKd@ zVicsrkjD&5wc9eTZL%&6<6V<@KmVr9ZRV&j3=Q&dU27K2!-2IjiqO(cgmLyCD)WOf zclTg8?8`(K`Xw0lTNuM~4YqL2<5^=d>O)lK=KYF;lV^*i9EM!uGxSu$D>DhY5g=@E z1{o8A_hrH^6^wHGhmGknWKYfTdk5$k!kl{gOt<{>_Nqm z?ID)?_p!HONFc{F!pIg^`GRkz*bp#3{08O&+>pa=1TTA7S*m#FG5O~1U6M2x;?}zl zmR;yrU0x{mlA|!p7!wTnhFo;PBKlq96uUlrtD}z1;hfowbJ;WetM5f|?SEoaNin=) zZ-+n4_R5<8NID?89*h;=V&by7k&ncxUa+?^Lsk6Wv$cZJDrO8q3UbT!l|Tj)6eYAo zXT&o|>NyW$RQHH`_S_WWHXAdM?)qlqE_`6+f)hQxGsTa^5O8FQfBLARc>Uu?r1%pU z(vL)OFFCSLqqvJMjpDa{fD6AzXu0ph12!WGHVyz=5BlMF-XNaV-9NlM!+>WA@Q~qlxbf!8~w>gXeu$wao+>N8Nu854Ho|tpZM)#-&UQ#-iHxcx`X`*TwU)!;;b2t zVRKvNjM&|w@7(WXzua2+bf^mHb!JXf>J;aDDIwb~fK;_*J* zqH=zULA#yfS6;;sI4|VD6{_eD#SxUQP#x!))kWYZD!C!r6@U+vN0;6Tj7|~Ke9JUi zX}9o6>S$UbgN2ah*t!DNpC&mTKlLO(eyl z%Q0mwPUV|3ADHM+>+82rFRZU`$F#rn$KlJd#>NdzEN>R}coiW7?yo=jA+EIPDLpfM z?eHDp99e14c?#*2I`1s4iV82|?jWT2@o=HQ*ubNLa6D+M*GV3?KPF}oJs*^Gi#GzP zzRO*Nn^Ya&Zu#p!!vyMFz$0~>jZjkt6Bx}Q?ig+TNQ1>epP5kRQ&24g$UF@@}5%F6hy^55MKV-SHWw|mr!i4oo>J~`_K7Y zZQ zV@WdAhsai|ozL-1j2#x?#d3mH-cO|F4rF1p7irZzc4xHTt<8B6j>vA}j~vvCL4rP! zgFg7emsnDda#KDwr=ZsTteJ68o0T7FZ0+dCYS@(-IOYay^GAbyoHt^(#f?MS^p?(H zWBRl?FQla{hl!W8v81ycw1{AY{oglX;BBDG$19h^r~7&$AJ=Q+=%vNW!8aabrS6J|cEO!4vz za7~%8GOZ@aX^8jGKcfv!7Tz8q3rE+bk`5+9NLQ>mV2cKpn#Lgg^BQ;CWljV$;U(b^ zOob1_i+QiXPzkvR`nf>nO=xw?B0t0~^_vUmfU!=zGSp9boZrK)rtln0Q_td?iPfKj zg^V`v+^29To{qE&&y9eAbMoA8o~L;d;=I+rYQ((V!}ouN6-HYS4;Z!g8@wqNM2`s! zZZ=mijy((l&61q)c-gG{OyNkDjU0)>&Z1=6V>5;8Qqv08 zxyk!=4n}hOa^(KJ&z_(@=i>tclS%CdKyZXCP#<3Lhp!5s&hK5t4)*mWmo~J}5YGUp z1rCUjax5-EFtzkSVS8wkKzZSg`W6nk6)ENNmNbfb<8rm|A)^6E* zG1?Vj_TD^tTG+WkbE; z*qd*QWS(dCc0N;;(rU*Bon6Tn+Qg6xNQt?Xk<<}n`LYeABQR2R1f$b*1f$b*1f$b* z1f!EWg3+QQ0D39}aA`WqQz)Vs80{(sjD%v~7hx{G>(5DDz~dDa=y}Ar8q@{Wf;=!7 zk1~m-1q+^z1T)yUm$B>J{ zqo?=9y8)1cUh*HQm^Y6^%(ZweIfxgKSL${MHJJV!CPEO?kAVMFte@k7cjx|O;#>u; zJR9KI%H6FDZvowgUK%roL&llL8Ti%jJkN*6f}~8BjYEXX5J7q6jrh^nuRU^f?FvL+oQN*( z)6)ozI@!f{EDNlem~=nIhi$l5!BY)3=L+(sf_(yL!Kbs;v*)}5V99gm>gjX;7hOGj z&b#m`HD@YbT3)12O&gnlw}88NG`(9Qb)S^fopVO&jIL5=B8}L5w`RYIN~kxzV`EAJ zd`L&V&pu`i9I>6Xa_7(=x>3z#y!)NN)q5R;W zt8p-I`Uu=7dJ{w_yR$!HoKlv9&(z|f{78)7O+OYf3Wib_KKmsg<&1D!Vn&Er>%2=- zW`unvBT8~c_&UWpR2!V#UU`~3Bm5LpayTRWgbvOKUqmzq`?=!a)Nm%`r}Gp5v^DH3 zv*cU$2?!JJTgJOM;o>q*yTXvsl^LywWOM0@1g`^Uv6g$iysryCyK`wMd$r zunNC}H%-sa4v+{i~{-tM#&5pD{p$mOO=lb+Joij+sEqchsFX7#X) zSAm;cG3TowO(q?tX|RlSZj9NCk&c%o(&lmJk%}gKp!xHn--_r$6OYemPGOL&D9z20 zoxbZasXf47t+E;xFMQzB#aZiT9WIwlp=xM;SW5#Sh?awt*4S<*Fi6ZWH8A+^DLJN7J1~QM!2M=F(ehtldjf+ zXF6w0fXx>&ys-3)B^b8}lfh{jOEAuxrUa*EEWwx*BY1h|j0q5Bh!>Wgu>_x#k~F=> z5*$hkPR&??ZD=Z@2Km5#4^D1Uz_Ot95XGA#8pA(Ia`p3jgQ5c^!z5YrEkKNIupd(SEzWf9@7f`7ytM^^8CAD#?_hte_r#ovE0o<79$ z*lEo|Hk7o&n; z$++y}A7T6A`}ir9FMqZ12h&UVvi}dqBYe4i!w)Wx@a6m;jz{?Nf*+1Y_|pHw@d#hO zwEhRvNBHu0KOB$n}&D;PsikU?;=KpgS;Et-4sucUy*gXLTBmp<~%KLzW4 zgy%V@$TxSpf>TdLxFQYoG4D)7;g0a6f*Utc`LWNd%DeD9_nTX_S>S27UCZM$h<;nV z7H2y4jmyl?s(8_}+2HEKXf_Vv17C;w_|Op8hV!crmlg=?r#?mM!?nfU_>b%$bO4+y z#`}s>W_i$R3jg%?AJYCXa z+=6NQYw!OW(@9JY{u8V-l31q!D+=qw)2H!!vFBl?;GT6ZaDRpAL`;-AoDS~+743F_ z&{DE3`DT+E@`rNhcV7#5<0M2{hB86X3>b5ZcmHYXVGC9(-gcb=B~DZr^&m8Jc>^0s zmZBPbzxtRHY;Qt76%K7XG{(B1zAMBp7OGm}jiP!|DN&}q{|(|Gr#QYwQz@PQgwwtcWd`lR zaz!XtEAo^T7=kkpoJ_x*K4k>|aX6iGRHD>J1ib36za$a$4n%D+cx?i6LaFIZfVlY> zA0Rhl4aJ5J$AH&7i&|n=l9mmH7Al9-w-US@ewoanAT0;yK}n>0U6Zd0c!`E36YYl6 zEf!V+_6?Y=r=`PgKr&tX#fj=Xot};lF(0{*jYxMGRz<--Gblk8(Nm25sXzU0w-!f27N#8WU7D+R;xu7UwEem6Z2F(x90QAfe=5BKe~w?6zr zDj3wQK5ovdN5sk0xVeL_!wx$7F02Y$)c(J#bin37Vtf9Hhy`t4cALuBjC(by_cq|O8_apk)yZ#> zQu*-LBBi7&`e1LW%DJ^Z7(@t8@cFpL{Xwu{tF(|PY@2n{esdn)pgg(_bKa9h{t%Bhl+vl7a1P)G5W(5UZM^ z8=T>*$K{fSUA>{Q@cBlPaYUwr1j`P91n&stn;Kess{rRixsON1nca*{Gw>grxO&=( z4~S9^tRQRyKG1KR=*#l?h;s}!L=gI_3Vp3p=y(;nPKB;lq1iZSTfITt>=W2tBA^)n zxwF8I6pZE1Hy7WaQon-`eV5KXJGs(|>>33$Qb4@%scwJDgGTPSiJg~8t~Ls9j%by< z~f?lpKCz<2M-x0@J^WE)0Bz%$f~O zp8V;PCk(+#GaHq!(%qPi6`8A{7*u1aj{AZkf7RgU+#ae|9+L;iV!zWnlPX?Qcjd07#`~^ z3SYLG3k~y_5Y|>W{H2bV!vMnkF^J{oaTz*VB9Gvge=U(E3D<)O*JG|r=JBgB`1+h@ zF6TjI3ws&<8exE~fh9r_^}9I`l|sp{zvc!Yz`F}eVuqDro2QOj9R+QNe-fqg*s$sS`)~&uvm~qwm8QrS3%sAm%m`7eB zMUVy#|%H~EaX>~=O!(tuR)S?p$ z|E!vu;8MkN8d`LwQ}9~^<Q*q*Ta?vOy%C1d&?W(_Gnzl^aM?V!>{;6$2g=OggO&a71!dwpA5`#0LZlr&Wr zAr@>p^t5k>|2(5TYt}?=gXBdwZ*9Z#5nAn6-kt`RW;luyF4hp{?sLepjj*24h6L;- z$pn#FLt~12aZ77V@zIc$u;~VWG|Q@DgWwt96FX3vK$Y76I9}ddFR-c}Ltt#8-&{lo z-cO%^58iB&FJ8JYhu4!GBN}H-1&E};IgHDo6p@=+sA8N~@9i&uUosULWBF1vX z(uDSSCgRt>39%4Bx3+Q-2hS0kwCas0#b5|j1$Rm07H2q%g923jUkhO00n&6T zE9+NIN=)S(^_uU9uz?YVe@BE8MCjb^D}@e#j$s8GwK=2M5Gxl6)mB!Gb)lyKiY}8M zn?XC8`BbR&BWMwK-K?q^h!&`#gmL>sFax}=SyeM7fO5qRD9qs7tFYC;OJCM2WLO#k z@8|Qsqt)_(cAVs?8V@L(M;GVtsl= zNu<*sr%?F{=hEC$0tpfFEvfc>BBX$-$=aj{=?nk=ry@kFYGJeg8)5{-Qc^*y+>9io zAe3Nm`QjI1n(Pr#^&NIG@RG0=`i?SOsnUZ3{>1bk;+2ZP98RrQIOCK)X-eCgRRjQQ zsf6B|3?=87RRma7y12=NR#m0A$#+O44Wr6J=ad!^c2X$e>`lsg1z8gM--~7SBix69 zq3Uv!uM^Lof*3!5=l_K@<-f=C+ZnSchYRv@lAW#e zK0KhPOnRhI%DZTxfHVj~lC5L^PqIJQ4!d&IBW$7uZthp^06^xhgE#m$nGzxkO&%ZM zQ6|qb>Kwr--g0&Pv$ASb*1;tZEjQ0&lht@5h_s zwW>L+S&JXUF9g*P?U_xXhCLxuz@~t)dM!XG7^(7CkjX|J(SXS&i-4}Ch{H6!>SB1Y zp^*p092R$&nTxVjzH+nzor_cZ`1xGh6(O=z(pe_9-OQ#kIkQj@GklSbj

    8hdCN5 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�L-=VsrVRKexuMI&?^$NkKTXyGDAG;TkFBX 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 z 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 SmM&`{-(&t2VGo6p9Fyr%p+s>_ST!Z1*o$n`R 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